/*
 * Copyright (c) "Neo4j"
 * Neo4j Sweden AB [http://neo4j.com]
 *
 * This file is part of Neo4j.
 *
 * Neo4j is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.neo4j.gds.core.compression.packed;

import org.neo4j.internal.unsafe.UnsafeUtil;

/**
 * This class is generated by src/main.rs
 * Do not edit this file directly.
 */
public final class AdjacencyPacking {

    private AdjacencyPacking() {
    }

    public static final int BLOCK_SIZE = 64;

    public static int advanceValueOffset(int valuesStart) {
        return valuesStart + BLOCK_SIZE;
    }

    public static long pack(int bits, long[] values, int valuesStart, long packedPtr) {
        assert bits <= 64 : "Bits must be at most 64 but was " + bits;
        return PACKERS[bits].pack(values, valuesStart, packedPtr);
    }

    @FunctionalInterface
    private interface Packer {

        long pack(long[] values, int valuesStart, long packedPtr);
    }

    private static final Packer[] PACKERS = {
        AdjacencyPacking::pack0,
        AdjacencyPacking::pack1,
        AdjacencyPacking::pack2,
        AdjacencyPacking::pack3,
        AdjacencyPacking::pack4,
        AdjacencyPacking::pack5,
        AdjacencyPacking::pack6,
        AdjacencyPacking::pack7,
        AdjacencyPacking::pack8,
        AdjacencyPacking::pack9,
        AdjacencyPacking::pack10,
        AdjacencyPacking::pack11,
        AdjacencyPacking::pack12,
        AdjacencyPacking::pack13,
        AdjacencyPacking::pack14,
        AdjacencyPacking::pack15,
        AdjacencyPacking::pack16,
        AdjacencyPacking::pack17,
        AdjacencyPacking::pack18,
        AdjacencyPacking::pack19,
        AdjacencyPacking::pack20,
        AdjacencyPacking::pack21,
        AdjacencyPacking::pack22,
        AdjacencyPacking::pack23,
        AdjacencyPacking::pack24,
        AdjacencyPacking::pack25,
        AdjacencyPacking::pack26,
        AdjacencyPacking::pack27,
        AdjacencyPacking::pack28,
        AdjacencyPacking::pack29,
        AdjacencyPacking::pack30,
        AdjacencyPacking::pack31,
        AdjacencyPacking::pack32,
        AdjacencyPacking::pack33,
        AdjacencyPacking::pack34,
        AdjacencyPacking::pack35,
        AdjacencyPacking::pack36,
        AdjacencyPacking::pack37,
        AdjacencyPacking::pack38,
        AdjacencyPacking::pack39,
        AdjacencyPacking::pack40,
        AdjacencyPacking::pack41,
        AdjacencyPacking::pack42,
        AdjacencyPacking::pack43,
        AdjacencyPacking::pack44,
        AdjacencyPacking::pack45,
        AdjacencyPacking::pack46,
        AdjacencyPacking::pack47,
        AdjacencyPacking::pack48,
        AdjacencyPacking::pack49,
        AdjacencyPacking::pack50,
        AdjacencyPacking::pack51,
        AdjacencyPacking::pack52,
        AdjacencyPacking::pack53,
        AdjacencyPacking::pack54,
        AdjacencyPacking::pack55,
        AdjacencyPacking::pack56,
        AdjacencyPacking::pack57,
        AdjacencyPacking::pack58,
        AdjacencyPacking::pack59,
        AdjacencyPacking::pack60,
        AdjacencyPacking::pack61,
        AdjacencyPacking::pack62,
        AdjacencyPacking::pack63,
        AdjacencyPacking::pack64,
    };

    public static long loopPack(int bits, long[] values, int valuesStart, int valuesLength, long packedPtr) {
        assert bits <= 64 : "Bits must be at most 64 but was " + bits;
        return LOOP_PACKERS[bits].loopPack(values, valuesStart, valuesLength, packedPtr);
    }

    @FunctionalInterface
    private interface LoopPacker {

        long loopPack(long[] values, int valuesStart, int valuesLength, long packedPtr);
    }

    private static final LoopPacker[] LOOP_PACKERS = {
        AdjacencyPacking::packLoop0,
        AdjacencyPacking::packLoop1,
        AdjacencyPacking::packLoop2,
        AdjacencyPacking::packLoop3,
        AdjacencyPacking::packLoop4,
        AdjacencyPacking::packLoop5,
        AdjacencyPacking::packLoop6,
        AdjacencyPacking::packLoop7,
        AdjacencyPacking::packLoop8,
        AdjacencyPacking::packLoop9,
        AdjacencyPacking::packLoop10,
        AdjacencyPacking::packLoop11,
        AdjacencyPacking::packLoop12,
        AdjacencyPacking::packLoop13,
        AdjacencyPacking::packLoop14,
        AdjacencyPacking::packLoop15,
        AdjacencyPacking::packLoop16,
        AdjacencyPacking::packLoop17,
        AdjacencyPacking::packLoop18,
        AdjacencyPacking::packLoop19,
        AdjacencyPacking::packLoop20,
        AdjacencyPacking::packLoop21,
        AdjacencyPacking::packLoop22,
        AdjacencyPacking::packLoop23,
        AdjacencyPacking::packLoop24,
        AdjacencyPacking::packLoop25,
        AdjacencyPacking::packLoop26,
        AdjacencyPacking::packLoop27,
        AdjacencyPacking::packLoop28,
        AdjacencyPacking::packLoop29,
        AdjacencyPacking::packLoop30,
        AdjacencyPacking::packLoop31,
        AdjacencyPacking::packLoop32,
        AdjacencyPacking::packLoop33,
        AdjacencyPacking::packLoop34,
        AdjacencyPacking::packLoop35,
        AdjacencyPacking::packLoop36,
        AdjacencyPacking::packLoop37,
        AdjacencyPacking::packLoop38,
        AdjacencyPacking::packLoop39,
        AdjacencyPacking::packLoop40,
        AdjacencyPacking::packLoop41,
        AdjacencyPacking::packLoop42,
        AdjacencyPacking::packLoop43,
        AdjacencyPacking::packLoop44,
        AdjacencyPacking::packLoop45,
        AdjacencyPacking::packLoop46,
        AdjacencyPacking::packLoop47,
        AdjacencyPacking::packLoop48,
        AdjacencyPacking::packLoop49,
        AdjacencyPacking::packLoop50,
        AdjacencyPacking::packLoop51,
        AdjacencyPacking::packLoop52,
        AdjacencyPacking::packLoop53,
        AdjacencyPacking::packLoop54,
        AdjacencyPacking::packLoop55,
        AdjacencyPacking::packLoop56,
        AdjacencyPacking::packLoop57,
        AdjacencyPacking::packLoop58,
        AdjacencyPacking::packLoop59,
        AdjacencyPacking::packLoop60,
        AdjacencyPacking::packLoop61,
        AdjacencyPacking::packLoop62,
        AdjacencyPacking::packLoop63,
        AdjacencyPacking::packLoop64,
    };

    /**
     * Packs 64 0-bit values into 0 bytes, touching 0 words.
     */
    private static long pack0(long[] values, int valuesStart, long packedPtr) {
        return packedPtr;
    }

    /**
     * Packs 64 1-bit values into 8 bytes, touching 1 word.
     */
    private static long pack1(long[] values, int valuesStart, long packedPtr) {
        // Touching 1 word
        long w0;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 1;
        w0 |= values[2 + valuesStart] << 2;
        w0 |= values[3 + valuesStart] << 3;
        w0 |= values[4 + valuesStart] << 4;
        w0 |= values[5 + valuesStart] << 5;
        w0 |= values[6 + valuesStart] << 6;
        w0 |= values[7 + valuesStart] << 7;
        w0 |= values[8 + valuesStart] << 8;
        w0 |= values[9 + valuesStart] << 9;
        w0 |= values[10 + valuesStart] << 10;
        w0 |= values[11 + valuesStart] << 11;
        w0 |= values[12 + valuesStart] << 12;
        w0 |= values[13 + valuesStart] << 13;
        w0 |= values[14 + valuesStart] << 14;
        w0 |= values[15 + valuesStart] << 15;
        w0 |= values[16 + valuesStart] << 16;
        w0 |= values[17 + valuesStart] << 17;
        w0 |= values[18 + valuesStart] << 18;
        w0 |= values[19 + valuesStart] << 19;
        w0 |= values[20 + valuesStart] << 20;
        w0 |= values[21 + valuesStart] << 21;
        w0 |= values[22 + valuesStart] << 22;
        w0 |= values[23 + valuesStart] << 23;
        w0 |= values[24 + valuesStart] << 24;
        w0 |= values[25 + valuesStart] << 25;
        w0 |= values[26 + valuesStart] << 26;
        w0 |= values[27 + valuesStart] << 27;
        w0 |= values[28 + valuesStart] << 28;
        w0 |= values[29 + valuesStart] << 29;
        w0 |= values[30 + valuesStart] << 30;
        w0 |= values[31 + valuesStart] << 31;
        w0 |= values[32 + valuesStart] << 32;
        w0 |= values[33 + valuesStart] << 33;
        w0 |= values[34 + valuesStart] << 34;
        w0 |= values[35 + valuesStart] << 35;
        w0 |= values[36 + valuesStart] << 36;
        w0 |= values[37 + valuesStart] << 37;
        w0 |= values[38 + valuesStart] << 38;
        w0 |= values[39 + valuesStart] << 39;
        w0 |= values[40 + valuesStart] << 40;
        w0 |= values[41 + valuesStart] << 41;
        w0 |= values[42 + valuesStart] << 42;
        w0 |= values[43 + valuesStart] << 43;
        w0 |= values[44 + valuesStart] << 44;
        w0 |= values[45 + valuesStart] << 45;
        w0 |= values[46 + valuesStart] << 46;
        w0 |= values[47 + valuesStart] << 47;
        w0 |= values[48 + valuesStart] << 48;
        w0 |= values[49 + valuesStart] << 49;
        w0 |= values[50 + valuesStart] << 50;
        w0 |= values[51 + valuesStart] << 51;
        w0 |= values[52 + valuesStart] << 52;
        w0 |= values[53 + valuesStart] << 53;
        w0 |= values[54 + valuesStart] << 54;
        w0 |= values[55 + valuesStart] << 55;
        w0 |= values[56 + valuesStart] << 56;
        w0 |= values[57 + valuesStart] << 57;
        w0 |= values[58 + valuesStart] << 58;
        w0 |= values[59 + valuesStart] << 59;
        w0 |= values[60 + valuesStart] << 60;
        w0 |= values[61 + valuesStart] << 61;
        w0 |= values[62 + valuesStart] << 62;
        w0 |= values[63 + valuesStart] << 63;
        // Write to 8 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        return 8 + packedPtr;
    }

    /**
     * Packs 64 2-bit values into 16 bytes, touching 2 words.
     */
    private static long pack2(long[] values, int valuesStart, long packedPtr) {
        // Touching 2 words
        long w0;
        long w1;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 2;
        w0 |= values[2 + valuesStart] << 4;
        w0 |= values[3 + valuesStart] << 6;
        w0 |= values[4 + valuesStart] << 8;
        w0 |= values[5 + valuesStart] << 10;
        w0 |= values[6 + valuesStart] << 12;
        w0 |= values[7 + valuesStart] << 14;
        w0 |= values[8 + valuesStart] << 16;
        w0 |= values[9 + valuesStart] << 18;
        w0 |= values[10 + valuesStart] << 20;
        w0 |= values[11 + valuesStart] << 22;
        w0 |= values[12 + valuesStart] << 24;
        w0 |= values[13 + valuesStart] << 26;
        w0 |= values[14 + valuesStart] << 28;
        w0 |= values[15 + valuesStart] << 30;
        w0 |= values[16 + valuesStart] << 32;
        w0 |= values[17 + valuesStart] << 34;
        w0 |= values[18 + valuesStart] << 36;
        w0 |= values[19 + valuesStart] << 38;
        w0 |= values[20 + valuesStart] << 40;
        w0 |= values[21 + valuesStart] << 42;
        w0 |= values[22 + valuesStart] << 44;
        w0 |= values[23 + valuesStart] << 46;
        w0 |= values[24 + valuesStart] << 48;
        w0 |= values[25 + valuesStart] << 50;
        w0 |= values[26 + valuesStart] << 52;
        w0 |= values[27 + valuesStart] << 54;
        w0 |= values[28 + valuesStart] << 56;
        w0 |= values[29 + valuesStart] << 58;
        w0 |= values[30 + valuesStart] << 60;
        w0 |= values[31 + valuesStart] << 62;
        w1 = values[32 + valuesStart];
        w1 |= values[33 + valuesStart] << 2;
        w1 |= values[34 + valuesStart] << 4;
        w1 |= values[35 + valuesStart] << 6;
        w1 |= values[36 + valuesStart] << 8;
        w1 |= values[37 + valuesStart] << 10;
        w1 |= values[38 + valuesStart] << 12;
        w1 |= values[39 + valuesStart] << 14;
        w1 |= values[40 + valuesStart] << 16;
        w1 |= values[41 + valuesStart] << 18;
        w1 |= values[42 + valuesStart] << 20;
        w1 |= values[43 + valuesStart] << 22;
        w1 |= values[44 + valuesStart] << 24;
        w1 |= values[45 + valuesStart] << 26;
        w1 |= values[46 + valuesStart] << 28;
        w1 |= values[47 + valuesStart] << 30;
        w1 |= values[48 + valuesStart] << 32;
        w1 |= values[49 + valuesStart] << 34;
        w1 |= values[50 + valuesStart] << 36;
        w1 |= values[51 + valuesStart] << 38;
        w1 |= values[52 + valuesStart] << 40;
        w1 |= values[53 + valuesStart] << 42;
        w1 |= values[54 + valuesStart] << 44;
        w1 |= values[55 + valuesStart] << 46;
        w1 |= values[56 + valuesStart] << 48;
        w1 |= values[57 + valuesStart] << 50;
        w1 |= values[58 + valuesStart] << 52;
        w1 |= values[59 + valuesStart] << 54;
        w1 |= values[60 + valuesStart] << 56;
        w1 |= values[61 + valuesStart] << 58;
        w1 |= values[62 + valuesStart] << 60;
        w1 |= values[63 + valuesStart] << 62;
        // Write to 16 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        return 16 + packedPtr;
    }

    /**
     * Packs 64 3-bit values into 24 bytes, touching 3 words.
     */
    private static long pack3(long[] values, int valuesStart, long packedPtr) {
        // Touching 3 words
        long w0;
        long w1;
        long w2;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 3;
        w0 |= values[2 + valuesStart] << 6;
        w0 |= values[3 + valuesStart] << 9;
        w0 |= values[4 + valuesStart] << 12;
        w0 |= values[5 + valuesStart] << 15;
        w0 |= values[6 + valuesStart] << 18;
        w0 |= values[7 + valuesStart] << 21;
        w0 |= values[8 + valuesStart] << 24;
        w0 |= values[9 + valuesStart] << 27;
        w0 |= values[10 + valuesStart] << 30;
        w0 |= values[11 + valuesStart] << 33;
        w0 |= values[12 + valuesStart] << 36;
        w0 |= values[13 + valuesStart] << 39;
        w0 |= values[14 + valuesStart] << 42;
        w0 |= values[15 + valuesStart] << 45;
        w0 |= values[16 + valuesStart] << 48;
        w0 |= values[17 + valuesStart] << 51;
        w0 |= values[18 + valuesStart] << 54;
        w0 |= values[19 + valuesStart] << 57;
        w0 |= values[20 + valuesStart] << 60;
        w0 |= values[21 + valuesStart] << 63;
        w1 = values[21 + valuesStart] >>> 1;
        w1 |= values[22 + valuesStart] << 2;
        w1 |= values[23 + valuesStart] << 5;
        w1 |= values[24 + valuesStart] << 8;
        w1 |= values[25 + valuesStart] << 11;
        w1 |= values[26 + valuesStart] << 14;
        w1 |= values[27 + valuesStart] << 17;
        w1 |= values[28 + valuesStart] << 20;
        w1 |= values[29 + valuesStart] << 23;
        w1 |= values[30 + valuesStart] << 26;
        w1 |= values[31 + valuesStart] << 29;
        w1 |= values[32 + valuesStart] << 32;
        w1 |= values[33 + valuesStart] << 35;
        w1 |= values[34 + valuesStart] << 38;
        w1 |= values[35 + valuesStart] << 41;
        w1 |= values[36 + valuesStart] << 44;
        w1 |= values[37 + valuesStart] << 47;
        w1 |= values[38 + valuesStart] << 50;
        w1 |= values[39 + valuesStart] << 53;
        w1 |= values[40 + valuesStart] << 56;
        w1 |= values[41 + valuesStart] << 59;
        w1 |= values[42 + valuesStart] << 62;
        w2 = values[42 + valuesStart] >>> 2;
        w2 |= values[43 + valuesStart] << 1;
        w2 |= values[44 + valuesStart] << 4;
        w2 |= values[45 + valuesStart] << 7;
        w2 |= values[46 + valuesStart] << 10;
        w2 |= values[47 + valuesStart] << 13;
        w2 |= values[48 + valuesStart] << 16;
        w2 |= values[49 + valuesStart] << 19;
        w2 |= values[50 + valuesStart] << 22;
        w2 |= values[51 + valuesStart] << 25;
        w2 |= values[52 + valuesStart] << 28;
        w2 |= values[53 + valuesStart] << 31;
        w2 |= values[54 + valuesStart] << 34;
        w2 |= values[55 + valuesStart] << 37;
        w2 |= values[56 + valuesStart] << 40;
        w2 |= values[57 + valuesStart] << 43;
        w2 |= values[58 + valuesStart] << 46;
        w2 |= values[59 + valuesStart] << 49;
        w2 |= values[60 + valuesStart] << 52;
        w2 |= values[61 + valuesStart] << 55;
        w2 |= values[62 + valuesStart] << 58;
        w2 |= values[63 + valuesStart] << 61;
        // Write to 24 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        return 24 + packedPtr;
    }

    /**
     * Packs 64 4-bit values into 32 bytes, touching 4 words.
     */
    private static long pack4(long[] values, int valuesStart, long packedPtr) {
        // Touching 4 words
        long w0;
        long w1;
        long w2;
        long w3;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 4;
        w0 |= values[2 + valuesStart] << 8;
        w0 |= values[3 + valuesStart] << 12;
        w0 |= values[4 + valuesStart] << 16;
        w0 |= values[5 + valuesStart] << 20;
        w0 |= values[6 + valuesStart] << 24;
        w0 |= values[7 + valuesStart] << 28;
        w0 |= values[8 + valuesStart] << 32;
        w0 |= values[9 + valuesStart] << 36;
        w0 |= values[10 + valuesStart] << 40;
        w0 |= values[11 + valuesStart] << 44;
        w0 |= values[12 + valuesStart] << 48;
        w0 |= values[13 + valuesStart] << 52;
        w0 |= values[14 + valuesStart] << 56;
        w0 |= values[15 + valuesStart] << 60;
        w1 = values[16 + valuesStart];
        w1 |= values[17 + valuesStart] << 4;
        w1 |= values[18 + valuesStart] << 8;
        w1 |= values[19 + valuesStart] << 12;
        w1 |= values[20 + valuesStart] << 16;
        w1 |= values[21 + valuesStart] << 20;
        w1 |= values[22 + valuesStart] << 24;
        w1 |= values[23 + valuesStart] << 28;
        w1 |= values[24 + valuesStart] << 32;
        w1 |= values[25 + valuesStart] << 36;
        w1 |= values[26 + valuesStart] << 40;
        w1 |= values[27 + valuesStart] << 44;
        w1 |= values[28 + valuesStart] << 48;
        w1 |= values[29 + valuesStart] << 52;
        w1 |= values[30 + valuesStart] << 56;
        w1 |= values[31 + valuesStart] << 60;
        w2 = values[32 + valuesStart];
        w2 |= values[33 + valuesStart] << 4;
        w2 |= values[34 + valuesStart] << 8;
        w2 |= values[35 + valuesStart] << 12;
        w2 |= values[36 + valuesStart] << 16;
        w2 |= values[37 + valuesStart] << 20;
        w2 |= values[38 + valuesStart] << 24;
        w2 |= values[39 + valuesStart] << 28;
        w2 |= values[40 + valuesStart] << 32;
        w2 |= values[41 + valuesStart] << 36;
        w2 |= values[42 + valuesStart] << 40;
        w2 |= values[43 + valuesStart] << 44;
        w2 |= values[44 + valuesStart] << 48;
        w2 |= values[45 + valuesStart] << 52;
        w2 |= values[46 + valuesStart] << 56;
        w2 |= values[47 + valuesStart] << 60;
        w3 = values[48 + valuesStart];
        w3 |= values[49 + valuesStart] << 4;
        w3 |= values[50 + valuesStart] << 8;
        w3 |= values[51 + valuesStart] << 12;
        w3 |= values[52 + valuesStart] << 16;
        w3 |= values[53 + valuesStart] << 20;
        w3 |= values[54 + valuesStart] << 24;
        w3 |= values[55 + valuesStart] << 28;
        w3 |= values[56 + valuesStart] << 32;
        w3 |= values[57 + valuesStart] << 36;
        w3 |= values[58 + valuesStart] << 40;
        w3 |= values[59 + valuesStart] << 44;
        w3 |= values[60 + valuesStart] << 48;
        w3 |= values[61 + valuesStart] << 52;
        w3 |= values[62 + valuesStart] << 56;
        w3 |= values[63 + valuesStart] << 60;
        // Write to 32 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        return 32 + packedPtr;
    }

    /**
     * Packs 64 5-bit values into 40 bytes, touching 5 words.
     */
    private static long pack5(long[] values, int valuesStart, long packedPtr) {
        // Touching 5 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 5;
        w0 |= values[2 + valuesStart] << 10;
        w0 |= values[3 + valuesStart] << 15;
        w0 |= values[4 + valuesStart] << 20;
        w0 |= values[5 + valuesStart] << 25;
        w0 |= values[6 + valuesStart] << 30;
        w0 |= values[7 + valuesStart] << 35;
        w0 |= values[8 + valuesStart] << 40;
        w0 |= values[9 + valuesStart] << 45;
        w0 |= values[10 + valuesStart] << 50;
        w0 |= values[11 + valuesStart] << 55;
        w0 |= values[12 + valuesStart] << 60;
        w1 = values[12 + valuesStart] >>> 4;
        w1 |= values[13 + valuesStart] << 1;
        w1 |= values[14 + valuesStart] << 6;
        w1 |= values[15 + valuesStart] << 11;
        w1 |= values[16 + valuesStart] << 16;
        w1 |= values[17 + valuesStart] << 21;
        w1 |= values[18 + valuesStart] << 26;
        w1 |= values[19 + valuesStart] << 31;
        w1 |= values[20 + valuesStart] << 36;
        w1 |= values[21 + valuesStart] << 41;
        w1 |= values[22 + valuesStart] << 46;
        w1 |= values[23 + valuesStart] << 51;
        w1 |= values[24 + valuesStart] << 56;
        w1 |= values[25 + valuesStart] << 61;
        w2 = values[25 + valuesStart] >>> 3;
        w2 |= values[26 + valuesStart] << 2;
        w2 |= values[27 + valuesStart] << 7;
        w2 |= values[28 + valuesStart] << 12;
        w2 |= values[29 + valuesStart] << 17;
        w2 |= values[30 + valuesStart] << 22;
        w2 |= values[31 + valuesStart] << 27;
        w2 |= values[32 + valuesStart] << 32;
        w2 |= values[33 + valuesStart] << 37;
        w2 |= values[34 + valuesStart] << 42;
        w2 |= values[35 + valuesStart] << 47;
        w2 |= values[36 + valuesStart] << 52;
        w2 |= values[37 + valuesStart] << 57;
        w2 |= values[38 + valuesStart] << 62;
        w3 = values[38 + valuesStart] >>> 2;
        w3 |= values[39 + valuesStart] << 3;
        w3 |= values[40 + valuesStart] << 8;
        w3 |= values[41 + valuesStart] << 13;
        w3 |= values[42 + valuesStart] << 18;
        w3 |= values[43 + valuesStart] << 23;
        w3 |= values[44 + valuesStart] << 28;
        w3 |= values[45 + valuesStart] << 33;
        w3 |= values[46 + valuesStart] << 38;
        w3 |= values[47 + valuesStart] << 43;
        w3 |= values[48 + valuesStart] << 48;
        w3 |= values[49 + valuesStart] << 53;
        w3 |= values[50 + valuesStart] << 58;
        w3 |= values[51 + valuesStart] << 63;
        w4 = values[51 + valuesStart] >>> 1;
        w4 |= values[52 + valuesStart] << 4;
        w4 |= values[53 + valuesStart] << 9;
        w4 |= values[54 + valuesStart] << 14;
        w4 |= values[55 + valuesStart] << 19;
        w4 |= values[56 + valuesStart] << 24;
        w4 |= values[57 + valuesStart] << 29;
        w4 |= values[58 + valuesStart] << 34;
        w4 |= values[59 + valuesStart] << 39;
        w4 |= values[60 + valuesStart] << 44;
        w4 |= values[61 + valuesStart] << 49;
        w4 |= values[62 + valuesStart] << 54;
        w4 |= values[63 + valuesStart] << 59;
        // Write to 40 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        return 40 + packedPtr;
    }

    /**
     * Packs 64 6-bit values into 48 bytes, touching 6 words.
     */
    private static long pack6(long[] values, int valuesStart, long packedPtr) {
        // Touching 6 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 6;
        w0 |= values[2 + valuesStart] << 12;
        w0 |= values[3 + valuesStart] << 18;
        w0 |= values[4 + valuesStart] << 24;
        w0 |= values[5 + valuesStart] << 30;
        w0 |= values[6 + valuesStart] << 36;
        w0 |= values[7 + valuesStart] << 42;
        w0 |= values[8 + valuesStart] << 48;
        w0 |= values[9 + valuesStart] << 54;
        w0 |= values[10 + valuesStart] << 60;
        w1 = values[10 + valuesStart] >>> 4;
        w1 |= values[11 + valuesStart] << 2;
        w1 |= values[12 + valuesStart] << 8;
        w1 |= values[13 + valuesStart] << 14;
        w1 |= values[14 + valuesStart] << 20;
        w1 |= values[15 + valuesStart] << 26;
        w1 |= values[16 + valuesStart] << 32;
        w1 |= values[17 + valuesStart] << 38;
        w1 |= values[18 + valuesStart] << 44;
        w1 |= values[19 + valuesStart] << 50;
        w1 |= values[20 + valuesStart] << 56;
        w1 |= values[21 + valuesStart] << 62;
        w2 = values[21 + valuesStart] >>> 2;
        w2 |= values[22 + valuesStart] << 4;
        w2 |= values[23 + valuesStart] << 10;
        w2 |= values[24 + valuesStart] << 16;
        w2 |= values[25 + valuesStart] << 22;
        w2 |= values[26 + valuesStart] << 28;
        w2 |= values[27 + valuesStart] << 34;
        w2 |= values[28 + valuesStart] << 40;
        w2 |= values[29 + valuesStart] << 46;
        w2 |= values[30 + valuesStart] << 52;
        w2 |= values[31 + valuesStart] << 58;
        w3 = values[32 + valuesStart];
        w3 |= values[33 + valuesStart] << 6;
        w3 |= values[34 + valuesStart] << 12;
        w3 |= values[35 + valuesStart] << 18;
        w3 |= values[36 + valuesStart] << 24;
        w3 |= values[37 + valuesStart] << 30;
        w3 |= values[38 + valuesStart] << 36;
        w3 |= values[39 + valuesStart] << 42;
        w3 |= values[40 + valuesStart] << 48;
        w3 |= values[41 + valuesStart] << 54;
        w3 |= values[42 + valuesStart] << 60;
        w4 = values[42 + valuesStart] >>> 4;
        w4 |= values[43 + valuesStart] << 2;
        w4 |= values[44 + valuesStart] << 8;
        w4 |= values[45 + valuesStart] << 14;
        w4 |= values[46 + valuesStart] << 20;
        w4 |= values[47 + valuesStart] << 26;
        w4 |= values[48 + valuesStart] << 32;
        w4 |= values[49 + valuesStart] << 38;
        w4 |= values[50 + valuesStart] << 44;
        w4 |= values[51 + valuesStart] << 50;
        w4 |= values[52 + valuesStart] << 56;
        w4 |= values[53 + valuesStart] << 62;
        w5 = values[53 + valuesStart] >>> 2;
        w5 |= values[54 + valuesStart] << 4;
        w5 |= values[55 + valuesStart] << 10;
        w5 |= values[56 + valuesStart] << 16;
        w5 |= values[57 + valuesStart] << 22;
        w5 |= values[58 + valuesStart] << 28;
        w5 |= values[59 + valuesStart] << 34;
        w5 |= values[60 + valuesStart] << 40;
        w5 |= values[61 + valuesStart] << 46;
        w5 |= values[62 + valuesStart] << 52;
        w5 |= values[63 + valuesStart] << 58;
        // Write to 48 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        return 48 + packedPtr;
    }

    /**
     * Packs 64 7-bit values into 56 bytes, touching 7 words.
     */
    private static long pack7(long[] values, int valuesStart, long packedPtr) {
        // Touching 7 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 7;
        w0 |= values[2 + valuesStart] << 14;
        w0 |= values[3 + valuesStart] << 21;
        w0 |= values[4 + valuesStart] << 28;
        w0 |= values[5 + valuesStart] << 35;
        w0 |= values[6 + valuesStart] << 42;
        w0 |= values[7 + valuesStart] << 49;
        w0 |= values[8 + valuesStart] << 56;
        w0 |= values[9 + valuesStart] << 63;
        w1 = values[9 + valuesStart] >>> 1;
        w1 |= values[10 + valuesStart] << 6;
        w1 |= values[11 + valuesStart] << 13;
        w1 |= values[12 + valuesStart] << 20;
        w1 |= values[13 + valuesStart] << 27;
        w1 |= values[14 + valuesStart] << 34;
        w1 |= values[15 + valuesStart] << 41;
        w1 |= values[16 + valuesStart] << 48;
        w1 |= values[17 + valuesStart] << 55;
        w1 |= values[18 + valuesStart] << 62;
        w2 = values[18 + valuesStart] >>> 2;
        w2 |= values[19 + valuesStart] << 5;
        w2 |= values[20 + valuesStart] << 12;
        w2 |= values[21 + valuesStart] << 19;
        w2 |= values[22 + valuesStart] << 26;
        w2 |= values[23 + valuesStart] << 33;
        w2 |= values[24 + valuesStart] << 40;
        w2 |= values[25 + valuesStart] << 47;
        w2 |= values[26 + valuesStart] << 54;
        w2 |= values[27 + valuesStart] << 61;
        w3 = values[27 + valuesStart] >>> 3;
        w3 |= values[28 + valuesStart] << 4;
        w3 |= values[29 + valuesStart] << 11;
        w3 |= values[30 + valuesStart] << 18;
        w3 |= values[31 + valuesStart] << 25;
        w3 |= values[32 + valuesStart] << 32;
        w3 |= values[33 + valuesStart] << 39;
        w3 |= values[34 + valuesStart] << 46;
        w3 |= values[35 + valuesStart] << 53;
        w3 |= values[36 + valuesStart] << 60;
        w4 = values[36 + valuesStart] >>> 4;
        w4 |= values[37 + valuesStart] << 3;
        w4 |= values[38 + valuesStart] << 10;
        w4 |= values[39 + valuesStart] << 17;
        w4 |= values[40 + valuesStart] << 24;
        w4 |= values[41 + valuesStart] << 31;
        w4 |= values[42 + valuesStart] << 38;
        w4 |= values[43 + valuesStart] << 45;
        w4 |= values[44 + valuesStart] << 52;
        w4 |= values[45 + valuesStart] << 59;
        w5 = values[45 + valuesStart] >>> 5;
        w5 |= values[46 + valuesStart] << 2;
        w5 |= values[47 + valuesStart] << 9;
        w5 |= values[48 + valuesStart] << 16;
        w5 |= values[49 + valuesStart] << 23;
        w5 |= values[50 + valuesStart] << 30;
        w5 |= values[51 + valuesStart] << 37;
        w5 |= values[52 + valuesStart] << 44;
        w5 |= values[53 + valuesStart] << 51;
        w5 |= values[54 + valuesStart] << 58;
        w6 = values[54 + valuesStart] >>> 6;
        w6 |= values[55 + valuesStart] << 1;
        w6 |= values[56 + valuesStart] << 8;
        w6 |= values[57 + valuesStart] << 15;
        w6 |= values[58 + valuesStart] << 22;
        w6 |= values[59 + valuesStart] << 29;
        w6 |= values[60 + valuesStart] << 36;
        w6 |= values[61 + valuesStart] << 43;
        w6 |= values[62 + valuesStart] << 50;
        w6 |= values[63 + valuesStart] << 57;
        // Write to 56 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        return 56 + packedPtr;
    }

    /**
     * Packs 64 8-bit values into 64 bytes, touching 8 words.
     */
    private static long pack8(long[] values, int valuesStart, long packedPtr) {
        // Touching 8 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 8;
        w0 |= values[2 + valuesStart] << 16;
        w0 |= values[3 + valuesStart] << 24;
        w0 |= values[4 + valuesStart] << 32;
        w0 |= values[5 + valuesStart] << 40;
        w0 |= values[6 + valuesStart] << 48;
        w0 |= values[7 + valuesStart] << 56;
        w1 = values[8 + valuesStart];
        w1 |= values[9 + valuesStart] << 8;
        w1 |= values[10 + valuesStart] << 16;
        w1 |= values[11 + valuesStart] << 24;
        w1 |= values[12 + valuesStart] << 32;
        w1 |= values[13 + valuesStart] << 40;
        w1 |= values[14 + valuesStart] << 48;
        w1 |= values[15 + valuesStart] << 56;
        w2 = values[16 + valuesStart];
        w2 |= values[17 + valuesStart] << 8;
        w2 |= values[18 + valuesStart] << 16;
        w2 |= values[19 + valuesStart] << 24;
        w2 |= values[20 + valuesStart] << 32;
        w2 |= values[21 + valuesStart] << 40;
        w2 |= values[22 + valuesStart] << 48;
        w2 |= values[23 + valuesStart] << 56;
        w3 = values[24 + valuesStart];
        w3 |= values[25 + valuesStart] << 8;
        w3 |= values[26 + valuesStart] << 16;
        w3 |= values[27 + valuesStart] << 24;
        w3 |= values[28 + valuesStart] << 32;
        w3 |= values[29 + valuesStart] << 40;
        w3 |= values[30 + valuesStart] << 48;
        w3 |= values[31 + valuesStart] << 56;
        w4 = values[32 + valuesStart];
        w4 |= values[33 + valuesStart] << 8;
        w4 |= values[34 + valuesStart] << 16;
        w4 |= values[35 + valuesStart] << 24;
        w4 |= values[36 + valuesStart] << 32;
        w4 |= values[37 + valuesStart] << 40;
        w4 |= values[38 + valuesStart] << 48;
        w4 |= values[39 + valuesStart] << 56;
        w5 = values[40 + valuesStart];
        w5 |= values[41 + valuesStart] << 8;
        w5 |= values[42 + valuesStart] << 16;
        w5 |= values[43 + valuesStart] << 24;
        w5 |= values[44 + valuesStart] << 32;
        w5 |= values[45 + valuesStart] << 40;
        w5 |= values[46 + valuesStart] << 48;
        w5 |= values[47 + valuesStart] << 56;
        w6 = values[48 + valuesStart];
        w6 |= values[49 + valuesStart] << 8;
        w6 |= values[50 + valuesStart] << 16;
        w6 |= values[51 + valuesStart] << 24;
        w6 |= values[52 + valuesStart] << 32;
        w6 |= values[53 + valuesStart] << 40;
        w6 |= values[54 + valuesStart] << 48;
        w6 |= values[55 + valuesStart] << 56;
        w7 = values[56 + valuesStart];
        w7 |= values[57 + valuesStart] << 8;
        w7 |= values[58 + valuesStart] << 16;
        w7 |= values[59 + valuesStart] << 24;
        w7 |= values[60 + valuesStart] << 32;
        w7 |= values[61 + valuesStart] << 40;
        w7 |= values[62 + valuesStart] << 48;
        w7 |= values[63 + valuesStart] << 56;
        // Write to 64 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        return 64 + packedPtr;
    }

    /**
     * Packs 64 9-bit values into 72 bytes, touching 9 words.
     */
    private static long pack9(long[] values, int valuesStart, long packedPtr) {
        // Touching 9 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 9;
        w0 |= values[2 + valuesStart] << 18;
        w0 |= values[3 + valuesStart] << 27;
        w0 |= values[4 + valuesStart] << 36;
        w0 |= values[5 + valuesStart] << 45;
        w0 |= values[6 + valuesStart] << 54;
        w0 |= values[7 + valuesStart] << 63;
        w1 = values[7 + valuesStart] >>> 1;
        w1 |= values[8 + valuesStart] << 8;
        w1 |= values[9 + valuesStart] << 17;
        w1 |= values[10 + valuesStart] << 26;
        w1 |= values[11 + valuesStart] << 35;
        w1 |= values[12 + valuesStart] << 44;
        w1 |= values[13 + valuesStart] << 53;
        w1 |= values[14 + valuesStart] << 62;
        w2 = values[14 + valuesStart] >>> 2;
        w2 |= values[15 + valuesStart] << 7;
        w2 |= values[16 + valuesStart] << 16;
        w2 |= values[17 + valuesStart] << 25;
        w2 |= values[18 + valuesStart] << 34;
        w2 |= values[19 + valuesStart] << 43;
        w2 |= values[20 + valuesStart] << 52;
        w2 |= values[21 + valuesStart] << 61;
        w3 = values[21 + valuesStart] >>> 3;
        w3 |= values[22 + valuesStart] << 6;
        w3 |= values[23 + valuesStart] << 15;
        w3 |= values[24 + valuesStart] << 24;
        w3 |= values[25 + valuesStart] << 33;
        w3 |= values[26 + valuesStart] << 42;
        w3 |= values[27 + valuesStart] << 51;
        w3 |= values[28 + valuesStart] << 60;
        w4 = values[28 + valuesStart] >>> 4;
        w4 |= values[29 + valuesStart] << 5;
        w4 |= values[30 + valuesStart] << 14;
        w4 |= values[31 + valuesStart] << 23;
        w4 |= values[32 + valuesStart] << 32;
        w4 |= values[33 + valuesStart] << 41;
        w4 |= values[34 + valuesStart] << 50;
        w4 |= values[35 + valuesStart] << 59;
        w5 = values[35 + valuesStart] >>> 5;
        w5 |= values[36 + valuesStart] << 4;
        w5 |= values[37 + valuesStart] << 13;
        w5 |= values[38 + valuesStart] << 22;
        w5 |= values[39 + valuesStart] << 31;
        w5 |= values[40 + valuesStart] << 40;
        w5 |= values[41 + valuesStart] << 49;
        w5 |= values[42 + valuesStart] << 58;
        w6 = values[42 + valuesStart] >>> 6;
        w6 |= values[43 + valuesStart] << 3;
        w6 |= values[44 + valuesStart] << 12;
        w6 |= values[45 + valuesStart] << 21;
        w6 |= values[46 + valuesStart] << 30;
        w6 |= values[47 + valuesStart] << 39;
        w6 |= values[48 + valuesStart] << 48;
        w6 |= values[49 + valuesStart] << 57;
        w7 = values[49 + valuesStart] >>> 7;
        w7 |= values[50 + valuesStart] << 2;
        w7 |= values[51 + valuesStart] << 11;
        w7 |= values[52 + valuesStart] << 20;
        w7 |= values[53 + valuesStart] << 29;
        w7 |= values[54 + valuesStart] << 38;
        w7 |= values[55 + valuesStart] << 47;
        w7 |= values[56 + valuesStart] << 56;
        w8 = values[56 + valuesStart] >>> 8;
        w8 |= values[57 + valuesStart] << 1;
        w8 |= values[58 + valuesStart] << 10;
        w8 |= values[59 + valuesStart] << 19;
        w8 |= values[60 + valuesStart] << 28;
        w8 |= values[61 + valuesStart] << 37;
        w8 |= values[62 + valuesStart] << 46;
        w8 |= values[63 + valuesStart] << 55;
        // Write to 72 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        return 72 + packedPtr;
    }

    /**
     * Packs 64 10-bit values into 80 bytes, touching 10 words.
     */
    private static long pack10(long[] values, int valuesStart, long packedPtr) {
        // Touching 10 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 10;
        w0 |= values[2 + valuesStart] << 20;
        w0 |= values[3 + valuesStart] << 30;
        w0 |= values[4 + valuesStart] << 40;
        w0 |= values[5 + valuesStart] << 50;
        w0 |= values[6 + valuesStart] << 60;
        w1 = values[6 + valuesStart] >>> 4;
        w1 |= values[7 + valuesStart] << 6;
        w1 |= values[8 + valuesStart] << 16;
        w1 |= values[9 + valuesStart] << 26;
        w1 |= values[10 + valuesStart] << 36;
        w1 |= values[11 + valuesStart] << 46;
        w1 |= values[12 + valuesStart] << 56;
        w2 = values[12 + valuesStart] >>> 8;
        w2 |= values[13 + valuesStart] << 2;
        w2 |= values[14 + valuesStart] << 12;
        w2 |= values[15 + valuesStart] << 22;
        w2 |= values[16 + valuesStart] << 32;
        w2 |= values[17 + valuesStart] << 42;
        w2 |= values[18 + valuesStart] << 52;
        w2 |= values[19 + valuesStart] << 62;
        w3 = values[19 + valuesStart] >>> 2;
        w3 |= values[20 + valuesStart] << 8;
        w3 |= values[21 + valuesStart] << 18;
        w3 |= values[22 + valuesStart] << 28;
        w3 |= values[23 + valuesStart] << 38;
        w3 |= values[24 + valuesStart] << 48;
        w3 |= values[25 + valuesStart] << 58;
        w4 = values[25 + valuesStart] >>> 6;
        w4 |= values[26 + valuesStart] << 4;
        w4 |= values[27 + valuesStart] << 14;
        w4 |= values[28 + valuesStart] << 24;
        w4 |= values[29 + valuesStart] << 34;
        w4 |= values[30 + valuesStart] << 44;
        w4 |= values[31 + valuesStart] << 54;
        w5 = values[32 + valuesStart];
        w5 |= values[33 + valuesStart] << 10;
        w5 |= values[34 + valuesStart] << 20;
        w5 |= values[35 + valuesStart] << 30;
        w5 |= values[36 + valuesStart] << 40;
        w5 |= values[37 + valuesStart] << 50;
        w5 |= values[38 + valuesStart] << 60;
        w6 = values[38 + valuesStart] >>> 4;
        w6 |= values[39 + valuesStart] << 6;
        w6 |= values[40 + valuesStart] << 16;
        w6 |= values[41 + valuesStart] << 26;
        w6 |= values[42 + valuesStart] << 36;
        w6 |= values[43 + valuesStart] << 46;
        w6 |= values[44 + valuesStart] << 56;
        w7 = values[44 + valuesStart] >>> 8;
        w7 |= values[45 + valuesStart] << 2;
        w7 |= values[46 + valuesStart] << 12;
        w7 |= values[47 + valuesStart] << 22;
        w7 |= values[48 + valuesStart] << 32;
        w7 |= values[49 + valuesStart] << 42;
        w7 |= values[50 + valuesStart] << 52;
        w7 |= values[51 + valuesStart] << 62;
        w8 = values[51 + valuesStart] >>> 2;
        w8 |= values[52 + valuesStart] << 8;
        w8 |= values[53 + valuesStart] << 18;
        w8 |= values[54 + valuesStart] << 28;
        w8 |= values[55 + valuesStart] << 38;
        w8 |= values[56 + valuesStart] << 48;
        w8 |= values[57 + valuesStart] << 58;
        w9 = values[57 + valuesStart] >>> 6;
        w9 |= values[58 + valuesStart] << 4;
        w9 |= values[59 + valuesStart] << 14;
        w9 |= values[60 + valuesStart] << 24;
        w9 |= values[61 + valuesStart] << 34;
        w9 |= values[62 + valuesStart] << 44;
        w9 |= values[63 + valuesStart] << 54;
        // Write to 80 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        return 80 + packedPtr;
    }

    /**
     * Packs 64 11-bit values into 88 bytes, touching 11 words.
     */
    private static long pack11(long[] values, int valuesStart, long packedPtr) {
        // Touching 11 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 11;
        w0 |= values[2 + valuesStart] << 22;
        w0 |= values[3 + valuesStart] << 33;
        w0 |= values[4 + valuesStart] << 44;
        w0 |= values[5 + valuesStart] << 55;
        w1 = values[5 + valuesStart] >>> 9;
        w1 |= values[6 + valuesStart] << 2;
        w1 |= values[7 + valuesStart] << 13;
        w1 |= values[8 + valuesStart] << 24;
        w1 |= values[9 + valuesStart] << 35;
        w1 |= values[10 + valuesStart] << 46;
        w1 |= values[11 + valuesStart] << 57;
        w2 = values[11 + valuesStart] >>> 7;
        w2 |= values[12 + valuesStart] << 4;
        w2 |= values[13 + valuesStart] << 15;
        w2 |= values[14 + valuesStart] << 26;
        w2 |= values[15 + valuesStart] << 37;
        w2 |= values[16 + valuesStart] << 48;
        w2 |= values[17 + valuesStart] << 59;
        w3 = values[17 + valuesStart] >>> 5;
        w3 |= values[18 + valuesStart] << 6;
        w3 |= values[19 + valuesStart] << 17;
        w3 |= values[20 + valuesStart] << 28;
        w3 |= values[21 + valuesStart] << 39;
        w3 |= values[22 + valuesStart] << 50;
        w3 |= values[23 + valuesStart] << 61;
        w4 = values[23 + valuesStart] >>> 3;
        w4 |= values[24 + valuesStart] << 8;
        w4 |= values[25 + valuesStart] << 19;
        w4 |= values[26 + valuesStart] << 30;
        w4 |= values[27 + valuesStart] << 41;
        w4 |= values[28 + valuesStart] << 52;
        w4 |= values[29 + valuesStart] << 63;
        w5 = values[29 + valuesStart] >>> 1;
        w5 |= values[30 + valuesStart] << 10;
        w5 |= values[31 + valuesStart] << 21;
        w5 |= values[32 + valuesStart] << 32;
        w5 |= values[33 + valuesStart] << 43;
        w5 |= values[34 + valuesStart] << 54;
        w6 = values[34 + valuesStart] >>> 10;
        w6 |= values[35 + valuesStart] << 1;
        w6 |= values[36 + valuesStart] << 12;
        w6 |= values[37 + valuesStart] << 23;
        w6 |= values[38 + valuesStart] << 34;
        w6 |= values[39 + valuesStart] << 45;
        w6 |= values[40 + valuesStart] << 56;
        w7 = values[40 + valuesStart] >>> 8;
        w7 |= values[41 + valuesStart] << 3;
        w7 |= values[42 + valuesStart] << 14;
        w7 |= values[43 + valuesStart] << 25;
        w7 |= values[44 + valuesStart] << 36;
        w7 |= values[45 + valuesStart] << 47;
        w7 |= values[46 + valuesStart] << 58;
        w8 = values[46 + valuesStart] >>> 6;
        w8 |= values[47 + valuesStart] << 5;
        w8 |= values[48 + valuesStart] << 16;
        w8 |= values[49 + valuesStart] << 27;
        w8 |= values[50 + valuesStart] << 38;
        w8 |= values[51 + valuesStart] << 49;
        w8 |= values[52 + valuesStart] << 60;
        w9 = values[52 + valuesStart] >>> 4;
        w9 |= values[53 + valuesStart] << 7;
        w9 |= values[54 + valuesStart] << 18;
        w9 |= values[55 + valuesStart] << 29;
        w9 |= values[56 + valuesStart] << 40;
        w9 |= values[57 + valuesStart] << 51;
        w9 |= values[58 + valuesStart] << 62;
        w10 = values[58 + valuesStart] >>> 2;
        w10 |= values[59 + valuesStart] << 9;
        w10 |= values[60 + valuesStart] << 20;
        w10 |= values[61 + valuesStart] << 31;
        w10 |= values[62 + valuesStart] << 42;
        w10 |= values[63 + valuesStart] << 53;
        // Write to 88 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        return 88 + packedPtr;
    }

    /**
     * Packs 64 12-bit values into 96 bytes, touching 12 words.
     */
    private static long pack12(long[] values, int valuesStart, long packedPtr) {
        // Touching 12 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 12;
        w0 |= values[2 + valuesStart] << 24;
        w0 |= values[3 + valuesStart] << 36;
        w0 |= values[4 + valuesStart] << 48;
        w0 |= values[5 + valuesStart] << 60;
        w1 = values[5 + valuesStart] >>> 4;
        w1 |= values[6 + valuesStart] << 8;
        w1 |= values[7 + valuesStart] << 20;
        w1 |= values[8 + valuesStart] << 32;
        w1 |= values[9 + valuesStart] << 44;
        w1 |= values[10 + valuesStart] << 56;
        w2 = values[10 + valuesStart] >>> 8;
        w2 |= values[11 + valuesStart] << 4;
        w2 |= values[12 + valuesStart] << 16;
        w2 |= values[13 + valuesStart] << 28;
        w2 |= values[14 + valuesStart] << 40;
        w2 |= values[15 + valuesStart] << 52;
        w3 = values[16 + valuesStart];
        w3 |= values[17 + valuesStart] << 12;
        w3 |= values[18 + valuesStart] << 24;
        w3 |= values[19 + valuesStart] << 36;
        w3 |= values[20 + valuesStart] << 48;
        w3 |= values[21 + valuesStart] << 60;
        w4 = values[21 + valuesStart] >>> 4;
        w4 |= values[22 + valuesStart] << 8;
        w4 |= values[23 + valuesStart] << 20;
        w4 |= values[24 + valuesStart] << 32;
        w4 |= values[25 + valuesStart] << 44;
        w4 |= values[26 + valuesStart] << 56;
        w5 = values[26 + valuesStart] >>> 8;
        w5 |= values[27 + valuesStart] << 4;
        w5 |= values[28 + valuesStart] << 16;
        w5 |= values[29 + valuesStart] << 28;
        w5 |= values[30 + valuesStart] << 40;
        w5 |= values[31 + valuesStart] << 52;
        w6 = values[32 + valuesStart];
        w6 |= values[33 + valuesStart] << 12;
        w6 |= values[34 + valuesStart] << 24;
        w6 |= values[35 + valuesStart] << 36;
        w6 |= values[36 + valuesStart] << 48;
        w6 |= values[37 + valuesStart] << 60;
        w7 = values[37 + valuesStart] >>> 4;
        w7 |= values[38 + valuesStart] << 8;
        w7 |= values[39 + valuesStart] << 20;
        w7 |= values[40 + valuesStart] << 32;
        w7 |= values[41 + valuesStart] << 44;
        w7 |= values[42 + valuesStart] << 56;
        w8 = values[42 + valuesStart] >>> 8;
        w8 |= values[43 + valuesStart] << 4;
        w8 |= values[44 + valuesStart] << 16;
        w8 |= values[45 + valuesStart] << 28;
        w8 |= values[46 + valuesStart] << 40;
        w8 |= values[47 + valuesStart] << 52;
        w9 = values[48 + valuesStart];
        w9 |= values[49 + valuesStart] << 12;
        w9 |= values[50 + valuesStart] << 24;
        w9 |= values[51 + valuesStart] << 36;
        w9 |= values[52 + valuesStart] << 48;
        w9 |= values[53 + valuesStart] << 60;
        w10 = values[53 + valuesStart] >>> 4;
        w10 |= values[54 + valuesStart] << 8;
        w10 |= values[55 + valuesStart] << 20;
        w10 |= values[56 + valuesStart] << 32;
        w10 |= values[57 + valuesStart] << 44;
        w10 |= values[58 + valuesStart] << 56;
        w11 = values[58 + valuesStart] >>> 8;
        w11 |= values[59 + valuesStart] << 4;
        w11 |= values[60 + valuesStart] << 16;
        w11 |= values[61 + valuesStart] << 28;
        w11 |= values[62 + valuesStart] << 40;
        w11 |= values[63 + valuesStart] << 52;
        // Write to 96 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        return 96 + packedPtr;
    }

    /**
     * Packs 64 13-bit values into 104 bytes, touching 13 words.
     */
    private static long pack13(long[] values, int valuesStart, long packedPtr) {
        // Touching 13 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 13;
        w0 |= values[2 + valuesStart] << 26;
        w0 |= values[3 + valuesStart] << 39;
        w0 |= values[4 + valuesStart] << 52;
        w1 = values[4 + valuesStart] >>> 12;
        w1 |= values[5 + valuesStart] << 1;
        w1 |= values[6 + valuesStart] << 14;
        w1 |= values[7 + valuesStart] << 27;
        w1 |= values[8 + valuesStart] << 40;
        w1 |= values[9 + valuesStart] << 53;
        w2 = values[9 + valuesStart] >>> 11;
        w2 |= values[10 + valuesStart] << 2;
        w2 |= values[11 + valuesStart] << 15;
        w2 |= values[12 + valuesStart] << 28;
        w2 |= values[13 + valuesStart] << 41;
        w2 |= values[14 + valuesStart] << 54;
        w3 = values[14 + valuesStart] >>> 10;
        w3 |= values[15 + valuesStart] << 3;
        w3 |= values[16 + valuesStart] << 16;
        w3 |= values[17 + valuesStart] << 29;
        w3 |= values[18 + valuesStart] << 42;
        w3 |= values[19 + valuesStart] << 55;
        w4 = values[19 + valuesStart] >>> 9;
        w4 |= values[20 + valuesStart] << 4;
        w4 |= values[21 + valuesStart] << 17;
        w4 |= values[22 + valuesStart] << 30;
        w4 |= values[23 + valuesStart] << 43;
        w4 |= values[24 + valuesStart] << 56;
        w5 = values[24 + valuesStart] >>> 8;
        w5 |= values[25 + valuesStart] << 5;
        w5 |= values[26 + valuesStart] << 18;
        w5 |= values[27 + valuesStart] << 31;
        w5 |= values[28 + valuesStart] << 44;
        w5 |= values[29 + valuesStart] << 57;
        w6 = values[29 + valuesStart] >>> 7;
        w6 |= values[30 + valuesStart] << 6;
        w6 |= values[31 + valuesStart] << 19;
        w6 |= values[32 + valuesStart] << 32;
        w6 |= values[33 + valuesStart] << 45;
        w6 |= values[34 + valuesStart] << 58;
        w7 = values[34 + valuesStart] >>> 6;
        w7 |= values[35 + valuesStart] << 7;
        w7 |= values[36 + valuesStart] << 20;
        w7 |= values[37 + valuesStart] << 33;
        w7 |= values[38 + valuesStart] << 46;
        w7 |= values[39 + valuesStart] << 59;
        w8 = values[39 + valuesStart] >>> 5;
        w8 |= values[40 + valuesStart] << 8;
        w8 |= values[41 + valuesStart] << 21;
        w8 |= values[42 + valuesStart] << 34;
        w8 |= values[43 + valuesStart] << 47;
        w8 |= values[44 + valuesStart] << 60;
        w9 = values[44 + valuesStart] >>> 4;
        w9 |= values[45 + valuesStart] << 9;
        w9 |= values[46 + valuesStart] << 22;
        w9 |= values[47 + valuesStart] << 35;
        w9 |= values[48 + valuesStart] << 48;
        w9 |= values[49 + valuesStart] << 61;
        w10 = values[49 + valuesStart] >>> 3;
        w10 |= values[50 + valuesStart] << 10;
        w10 |= values[51 + valuesStart] << 23;
        w10 |= values[52 + valuesStart] << 36;
        w10 |= values[53 + valuesStart] << 49;
        w10 |= values[54 + valuesStart] << 62;
        w11 = values[54 + valuesStart] >>> 2;
        w11 |= values[55 + valuesStart] << 11;
        w11 |= values[56 + valuesStart] << 24;
        w11 |= values[57 + valuesStart] << 37;
        w11 |= values[58 + valuesStart] << 50;
        w11 |= values[59 + valuesStart] << 63;
        w12 = values[59 + valuesStart] >>> 1;
        w12 |= values[60 + valuesStart] << 12;
        w12 |= values[61 + valuesStart] << 25;
        w12 |= values[62 + valuesStart] << 38;
        w12 |= values[63 + valuesStart] << 51;
        // Write to 104 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        return 104 + packedPtr;
    }

    /**
     * Packs 64 14-bit values into 112 bytes, touching 14 words.
     */
    private static long pack14(long[] values, int valuesStart, long packedPtr) {
        // Touching 14 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 14;
        w0 |= values[2 + valuesStart] << 28;
        w0 |= values[3 + valuesStart] << 42;
        w0 |= values[4 + valuesStart] << 56;
        w1 = values[4 + valuesStart] >>> 8;
        w1 |= values[5 + valuesStart] << 6;
        w1 |= values[6 + valuesStart] << 20;
        w1 |= values[7 + valuesStart] << 34;
        w1 |= values[8 + valuesStart] << 48;
        w1 |= values[9 + valuesStart] << 62;
        w2 = values[9 + valuesStart] >>> 2;
        w2 |= values[10 + valuesStart] << 12;
        w2 |= values[11 + valuesStart] << 26;
        w2 |= values[12 + valuesStart] << 40;
        w2 |= values[13 + valuesStart] << 54;
        w3 = values[13 + valuesStart] >>> 10;
        w3 |= values[14 + valuesStart] << 4;
        w3 |= values[15 + valuesStart] << 18;
        w3 |= values[16 + valuesStart] << 32;
        w3 |= values[17 + valuesStart] << 46;
        w3 |= values[18 + valuesStart] << 60;
        w4 = values[18 + valuesStart] >>> 4;
        w4 |= values[19 + valuesStart] << 10;
        w4 |= values[20 + valuesStart] << 24;
        w4 |= values[21 + valuesStart] << 38;
        w4 |= values[22 + valuesStart] << 52;
        w5 = values[22 + valuesStart] >>> 12;
        w5 |= values[23 + valuesStart] << 2;
        w5 |= values[24 + valuesStart] << 16;
        w5 |= values[25 + valuesStart] << 30;
        w5 |= values[26 + valuesStart] << 44;
        w5 |= values[27 + valuesStart] << 58;
        w6 = values[27 + valuesStart] >>> 6;
        w6 |= values[28 + valuesStart] << 8;
        w6 |= values[29 + valuesStart] << 22;
        w6 |= values[30 + valuesStart] << 36;
        w6 |= values[31 + valuesStart] << 50;
        w7 = values[32 + valuesStart];
        w7 |= values[33 + valuesStart] << 14;
        w7 |= values[34 + valuesStart] << 28;
        w7 |= values[35 + valuesStart] << 42;
        w7 |= values[36 + valuesStart] << 56;
        w8 = values[36 + valuesStart] >>> 8;
        w8 |= values[37 + valuesStart] << 6;
        w8 |= values[38 + valuesStart] << 20;
        w8 |= values[39 + valuesStart] << 34;
        w8 |= values[40 + valuesStart] << 48;
        w8 |= values[41 + valuesStart] << 62;
        w9 = values[41 + valuesStart] >>> 2;
        w9 |= values[42 + valuesStart] << 12;
        w9 |= values[43 + valuesStart] << 26;
        w9 |= values[44 + valuesStart] << 40;
        w9 |= values[45 + valuesStart] << 54;
        w10 = values[45 + valuesStart] >>> 10;
        w10 |= values[46 + valuesStart] << 4;
        w10 |= values[47 + valuesStart] << 18;
        w10 |= values[48 + valuesStart] << 32;
        w10 |= values[49 + valuesStart] << 46;
        w10 |= values[50 + valuesStart] << 60;
        w11 = values[50 + valuesStart] >>> 4;
        w11 |= values[51 + valuesStart] << 10;
        w11 |= values[52 + valuesStart] << 24;
        w11 |= values[53 + valuesStart] << 38;
        w11 |= values[54 + valuesStart] << 52;
        w12 = values[54 + valuesStart] >>> 12;
        w12 |= values[55 + valuesStart] << 2;
        w12 |= values[56 + valuesStart] << 16;
        w12 |= values[57 + valuesStart] << 30;
        w12 |= values[58 + valuesStart] << 44;
        w12 |= values[59 + valuesStart] << 58;
        w13 = values[59 + valuesStart] >>> 6;
        w13 |= values[60 + valuesStart] << 8;
        w13 |= values[61 + valuesStart] << 22;
        w13 |= values[62 + valuesStart] << 36;
        w13 |= values[63 + valuesStart] << 50;
        // Write to 112 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        return 112 + packedPtr;
    }

    /**
     * Packs 64 15-bit values into 120 bytes, touching 15 words.
     */
    private static long pack15(long[] values, int valuesStart, long packedPtr) {
        // Touching 15 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 15;
        w0 |= values[2 + valuesStart] << 30;
        w0 |= values[3 + valuesStart] << 45;
        w0 |= values[4 + valuesStart] << 60;
        w1 = values[4 + valuesStart] >>> 4;
        w1 |= values[5 + valuesStart] << 11;
        w1 |= values[6 + valuesStart] << 26;
        w1 |= values[7 + valuesStart] << 41;
        w1 |= values[8 + valuesStart] << 56;
        w2 = values[8 + valuesStart] >>> 8;
        w2 |= values[9 + valuesStart] << 7;
        w2 |= values[10 + valuesStart] << 22;
        w2 |= values[11 + valuesStart] << 37;
        w2 |= values[12 + valuesStart] << 52;
        w3 = values[12 + valuesStart] >>> 12;
        w3 |= values[13 + valuesStart] << 3;
        w3 |= values[14 + valuesStart] << 18;
        w3 |= values[15 + valuesStart] << 33;
        w3 |= values[16 + valuesStart] << 48;
        w3 |= values[17 + valuesStart] << 63;
        w4 = values[17 + valuesStart] >>> 1;
        w4 |= values[18 + valuesStart] << 14;
        w4 |= values[19 + valuesStart] << 29;
        w4 |= values[20 + valuesStart] << 44;
        w4 |= values[21 + valuesStart] << 59;
        w5 = values[21 + valuesStart] >>> 5;
        w5 |= values[22 + valuesStart] << 10;
        w5 |= values[23 + valuesStart] << 25;
        w5 |= values[24 + valuesStart] << 40;
        w5 |= values[25 + valuesStart] << 55;
        w6 = values[25 + valuesStart] >>> 9;
        w6 |= values[26 + valuesStart] << 6;
        w6 |= values[27 + valuesStart] << 21;
        w6 |= values[28 + valuesStart] << 36;
        w6 |= values[29 + valuesStart] << 51;
        w7 = values[29 + valuesStart] >>> 13;
        w7 |= values[30 + valuesStart] << 2;
        w7 |= values[31 + valuesStart] << 17;
        w7 |= values[32 + valuesStart] << 32;
        w7 |= values[33 + valuesStart] << 47;
        w7 |= values[34 + valuesStart] << 62;
        w8 = values[34 + valuesStart] >>> 2;
        w8 |= values[35 + valuesStart] << 13;
        w8 |= values[36 + valuesStart] << 28;
        w8 |= values[37 + valuesStart] << 43;
        w8 |= values[38 + valuesStart] << 58;
        w9 = values[38 + valuesStart] >>> 6;
        w9 |= values[39 + valuesStart] << 9;
        w9 |= values[40 + valuesStart] << 24;
        w9 |= values[41 + valuesStart] << 39;
        w9 |= values[42 + valuesStart] << 54;
        w10 = values[42 + valuesStart] >>> 10;
        w10 |= values[43 + valuesStart] << 5;
        w10 |= values[44 + valuesStart] << 20;
        w10 |= values[45 + valuesStart] << 35;
        w10 |= values[46 + valuesStart] << 50;
        w11 = values[46 + valuesStart] >>> 14;
        w11 |= values[47 + valuesStart] << 1;
        w11 |= values[48 + valuesStart] << 16;
        w11 |= values[49 + valuesStart] << 31;
        w11 |= values[50 + valuesStart] << 46;
        w11 |= values[51 + valuesStart] << 61;
        w12 = values[51 + valuesStart] >>> 3;
        w12 |= values[52 + valuesStart] << 12;
        w12 |= values[53 + valuesStart] << 27;
        w12 |= values[54 + valuesStart] << 42;
        w12 |= values[55 + valuesStart] << 57;
        w13 = values[55 + valuesStart] >>> 7;
        w13 |= values[56 + valuesStart] << 8;
        w13 |= values[57 + valuesStart] << 23;
        w13 |= values[58 + valuesStart] << 38;
        w13 |= values[59 + valuesStart] << 53;
        w14 = values[59 + valuesStart] >>> 11;
        w14 |= values[60 + valuesStart] << 4;
        w14 |= values[61 + valuesStart] << 19;
        w14 |= values[62 + valuesStart] << 34;
        w14 |= values[63 + valuesStart] << 49;
        // Write to 120 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        return 120 + packedPtr;
    }

    /**
     * Packs 64 16-bit values into 128 bytes, touching 16 words.
     */
    private static long pack16(long[] values, int valuesStart, long packedPtr) {
        // Touching 16 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 16;
        w0 |= values[2 + valuesStart] << 32;
        w0 |= values[3 + valuesStart] << 48;
        w1 = values[4 + valuesStart];
        w1 |= values[5 + valuesStart] << 16;
        w1 |= values[6 + valuesStart] << 32;
        w1 |= values[7 + valuesStart] << 48;
        w2 = values[8 + valuesStart];
        w2 |= values[9 + valuesStart] << 16;
        w2 |= values[10 + valuesStart] << 32;
        w2 |= values[11 + valuesStart] << 48;
        w3 = values[12 + valuesStart];
        w3 |= values[13 + valuesStart] << 16;
        w3 |= values[14 + valuesStart] << 32;
        w3 |= values[15 + valuesStart] << 48;
        w4 = values[16 + valuesStart];
        w4 |= values[17 + valuesStart] << 16;
        w4 |= values[18 + valuesStart] << 32;
        w4 |= values[19 + valuesStart] << 48;
        w5 = values[20 + valuesStart];
        w5 |= values[21 + valuesStart] << 16;
        w5 |= values[22 + valuesStart] << 32;
        w5 |= values[23 + valuesStart] << 48;
        w6 = values[24 + valuesStart];
        w6 |= values[25 + valuesStart] << 16;
        w6 |= values[26 + valuesStart] << 32;
        w6 |= values[27 + valuesStart] << 48;
        w7 = values[28 + valuesStart];
        w7 |= values[29 + valuesStart] << 16;
        w7 |= values[30 + valuesStart] << 32;
        w7 |= values[31 + valuesStart] << 48;
        w8 = values[32 + valuesStart];
        w8 |= values[33 + valuesStart] << 16;
        w8 |= values[34 + valuesStart] << 32;
        w8 |= values[35 + valuesStart] << 48;
        w9 = values[36 + valuesStart];
        w9 |= values[37 + valuesStart] << 16;
        w9 |= values[38 + valuesStart] << 32;
        w9 |= values[39 + valuesStart] << 48;
        w10 = values[40 + valuesStart];
        w10 |= values[41 + valuesStart] << 16;
        w10 |= values[42 + valuesStart] << 32;
        w10 |= values[43 + valuesStart] << 48;
        w11 = values[44 + valuesStart];
        w11 |= values[45 + valuesStart] << 16;
        w11 |= values[46 + valuesStart] << 32;
        w11 |= values[47 + valuesStart] << 48;
        w12 = values[48 + valuesStart];
        w12 |= values[49 + valuesStart] << 16;
        w12 |= values[50 + valuesStart] << 32;
        w12 |= values[51 + valuesStart] << 48;
        w13 = values[52 + valuesStart];
        w13 |= values[53 + valuesStart] << 16;
        w13 |= values[54 + valuesStart] << 32;
        w13 |= values[55 + valuesStart] << 48;
        w14 = values[56 + valuesStart];
        w14 |= values[57 + valuesStart] << 16;
        w14 |= values[58 + valuesStart] << 32;
        w14 |= values[59 + valuesStart] << 48;
        w15 = values[60 + valuesStart];
        w15 |= values[61 + valuesStart] << 16;
        w15 |= values[62 + valuesStart] << 32;
        w15 |= values[63 + valuesStart] << 48;
        // Write to 128 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        return 128 + packedPtr;
    }

    /**
     * Packs 64 17-bit values into 136 bytes, touching 17 words.
     */
    private static long pack17(long[] values, int valuesStart, long packedPtr) {
        // Touching 17 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 17;
        w0 |= values[2 + valuesStart] << 34;
        w0 |= values[3 + valuesStart] << 51;
        w1 = values[3 + valuesStart] >>> 13;
        w1 |= values[4 + valuesStart] << 4;
        w1 |= values[5 + valuesStart] << 21;
        w1 |= values[6 + valuesStart] << 38;
        w1 |= values[7 + valuesStart] << 55;
        w2 = values[7 + valuesStart] >>> 9;
        w2 |= values[8 + valuesStart] << 8;
        w2 |= values[9 + valuesStart] << 25;
        w2 |= values[10 + valuesStart] << 42;
        w2 |= values[11 + valuesStart] << 59;
        w3 = values[11 + valuesStart] >>> 5;
        w3 |= values[12 + valuesStart] << 12;
        w3 |= values[13 + valuesStart] << 29;
        w3 |= values[14 + valuesStart] << 46;
        w3 |= values[15 + valuesStart] << 63;
        w4 = values[15 + valuesStart] >>> 1;
        w4 |= values[16 + valuesStart] << 16;
        w4 |= values[17 + valuesStart] << 33;
        w4 |= values[18 + valuesStart] << 50;
        w5 = values[18 + valuesStart] >>> 14;
        w5 |= values[19 + valuesStart] << 3;
        w5 |= values[20 + valuesStart] << 20;
        w5 |= values[21 + valuesStart] << 37;
        w5 |= values[22 + valuesStart] << 54;
        w6 = values[22 + valuesStart] >>> 10;
        w6 |= values[23 + valuesStart] << 7;
        w6 |= values[24 + valuesStart] << 24;
        w6 |= values[25 + valuesStart] << 41;
        w6 |= values[26 + valuesStart] << 58;
        w7 = values[26 + valuesStart] >>> 6;
        w7 |= values[27 + valuesStart] << 11;
        w7 |= values[28 + valuesStart] << 28;
        w7 |= values[29 + valuesStart] << 45;
        w7 |= values[30 + valuesStart] << 62;
        w8 = values[30 + valuesStart] >>> 2;
        w8 |= values[31 + valuesStart] << 15;
        w8 |= values[32 + valuesStart] << 32;
        w8 |= values[33 + valuesStart] << 49;
        w9 = values[33 + valuesStart] >>> 15;
        w9 |= values[34 + valuesStart] << 2;
        w9 |= values[35 + valuesStart] << 19;
        w9 |= values[36 + valuesStart] << 36;
        w9 |= values[37 + valuesStart] << 53;
        w10 = values[37 + valuesStart] >>> 11;
        w10 |= values[38 + valuesStart] << 6;
        w10 |= values[39 + valuesStart] << 23;
        w10 |= values[40 + valuesStart] << 40;
        w10 |= values[41 + valuesStart] << 57;
        w11 = values[41 + valuesStart] >>> 7;
        w11 |= values[42 + valuesStart] << 10;
        w11 |= values[43 + valuesStart] << 27;
        w11 |= values[44 + valuesStart] << 44;
        w11 |= values[45 + valuesStart] << 61;
        w12 = values[45 + valuesStart] >>> 3;
        w12 |= values[46 + valuesStart] << 14;
        w12 |= values[47 + valuesStart] << 31;
        w12 |= values[48 + valuesStart] << 48;
        w13 = values[48 + valuesStart] >>> 16;
        w13 |= values[49 + valuesStart] << 1;
        w13 |= values[50 + valuesStart] << 18;
        w13 |= values[51 + valuesStart] << 35;
        w13 |= values[52 + valuesStart] << 52;
        w14 = values[52 + valuesStart] >>> 12;
        w14 |= values[53 + valuesStart] << 5;
        w14 |= values[54 + valuesStart] << 22;
        w14 |= values[55 + valuesStart] << 39;
        w14 |= values[56 + valuesStart] << 56;
        w15 = values[56 + valuesStart] >>> 8;
        w15 |= values[57 + valuesStart] << 9;
        w15 |= values[58 + valuesStart] << 26;
        w15 |= values[59 + valuesStart] << 43;
        w15 |= values[60 + valuesStart] << 60;
        w16 = values[60 + valuesStart] >>> 4;
        w16 |= values[61 + valuesStart] << 13;
        w16 |= values[62 + valuesStart] << 30;
        w16 |= values[63 + valuesStart] << 47;
        // Write to 136 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        return 136 + packedPtr;
    }

    /**
     * Packs 64 18-bit values into 144 bytes, touching 18 words.
     */
    private static long pack18(long[] values, int valuesStart, long packedPtr) {
        // Touching 18 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 18;
        w0 |= values[2 + valuesStart] << 36;
        w0 |= values[3 + valuesStart] << 54;
        w1 = values[3 + valuesStart] >>> 10;
        w1 |= values[4 + valuesStart] << 8;
        w1 |= values[5 + valuesStart] << 26;
        w1 |= values[6 + valuesStart] << 44;
        w1 |= values[7 + valuesStart] << 62;
        w2 = values[7 + valuesStart] >>> 2;
        w2 |= values[8 + valuesStart] << 16;
        w2 |= values[9 + valuesStart] << 34;
        w2 |= values[10 + valuesStart] << 52;
        w3 = values[10 + valuesStart] >>> 12;
        w3 |= values[11 + valuesStart] << 6;
        w3 |= values[12 + valuesStart] << 24;
        w3 |= values[13 + valuesStart] << 42;
        w3 |= values[14 + valuesStart] << 60;
        w4 = values[14 + valuesStart] >>> 4;
        w4 |= values[15 + valuesStart] << 14;
        w4 |= values[16 + valuesStart] << 32;
        w4 |= values[17 + valuesStart] << 50;
        w5 = values[17 + valuesStart] >>> 14;
        w5 |= values[18 + valuesStart] << 4;
        w5 |= values[19 + valuesStart] << 22;
        w5 |= values[20 + valuesStart] << 40;
        w5 |= values[21 + valuesStart] << 58;
        w6 = values[21 + valuesStart] >>> 6;
        w6 |= values[22 + valuesStart] << 12;
        w6 |= values[23 + valuesStart] << 30;
        w6 |= values[24 + valuesStart] << 48;
        w7 = values[24 + valuesStart] >>> 16;
        w7 |= values[25 + valuesStart] << 2;
        w7 |= values[26 + valuesStart] << 20;
        w7 |= values[27 + valuesStart] << 38;
        w7 |= values[28 + valuesStart] << 56;
        w8 = values[28 + valuesStart] >>> 8;
        w8 |= values[29 + valuesStart] << 10;
        w8 |= values[30 + valuesStart] << 28;
        w8 |= values[31 + valuesStart] << 46;
        w9 = values[32 + valuesStart];
        w9 |= values[33 + valuesStart] << 18;
        w9 |= values[34 + valuesStart] << 36;
        w9 |= values[35 + valuesStart] << 54;
        w10 = values[35 + valuesStart] >>> 10;
        w10 |= values[36 + valuesStart] << 8;
        w10 |= values[37 + valuesStart] << 26;
        w10 |= values[38 + valuesStart] << 44;
        w10 |= values[39 + valuesStart] << 62;
        w11 = values[39 + valuesStart] >>> 2;
        w11 |= values[40 + valuesStart] << 16;
        w11 |= values[41 + valuesStart] << 34;
        w11 |= values[42 + valuesStart] << 52;
        w12 = values[42 + valuesStart] >>> 12;
        w12 |= values[43 + valuesStart] << 6;
        w12 |= values[44 + valuesStart] << 24;
        w12 |= values[45 + valuesStart] << 42;
        w12 |= values[46 + valuesStart] << 60;
        w13 = values[46 + valuesStart] >>> 4;
        w13 |= values[47 + valuesStart] << 14;
        w13 |= values[48 + valuesStart] << 32;
        w13 |= values[49 + valuesStart] << 50;
        w14 = values[49 + valuesStart] >>> 14;
        w14 |= values[50 + valuesStart] << 4;
        w14 |= values[51 + valuesStart] << 22;
        w14 |= values[52 + valuesStart] << 40;
        w14 |= values[53 + valuesStart] << 58;
        w15 = values[53 + valuesStart] >>> 6;
        w15 |= values[54 + valuesStart] << 12;
        w15 |= values[55 + valuesStart] << 30;
        w15 |= values[56 + valuesStart] << 48;
        w16 = values[56 + valuesStart] >>> 16;
        w16 |= values[57 + valuesStart] << 2;
        w16 |= values[58 + valuesStart] << 20;
        w16 |= values[59 + valuesStart] << 38;
        w16 |= values[60 + valuesStart] << 56;
        w17 = values[60 + valuesStart] >>> 8;
        w17 |= values[61 + valuesStart] << 10;
        w17 |= values[62 + valuesStart] << 28;
        w17 |= values[63 + valuesStart] << 46;
        // Write to 144 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        return 144 + packedPtr;
    }

    /**
     * Packs 64 19-bit values into 152 bytes, touching 19 words.
     */
    private static long pack19(long[] values, int valuesStart, long packedPtr) {
        // Touching 19 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 19;
        w0 |= values[2 + valuesStart] << 38;
        w0 |= values[3 + valuesStart] << 57;
        w1 = values[3 + valuesStart] >>> 7;
        w1 |= values[4 + valuesStart] << 12;
        w1 |= values[5 + valuesStart] << 31;
        w1 |= values[6 + valuesStart] << 50;
        w2 = values[6 + valuesStart] >>> 14;
        w2 |= values[7 + valuesStart] << 5;
        w2 |= values[8 + valuesStart] << 24;
        w2 |= values[9 + valuesStart] << 43;
        w2 |= values[10 + valuesStart] << 62;
        w3 = values[10 + valuesStart] >>> 2;
        w3 |= values[11 + valuesStart] << 17;
        w3 |= values[12 + valuesStart] << 36;
        w3 |= values[13 + valuesStart] << 55;
        w4 = values[13 + valuesStart] >>> 9;
        w4 |= values[14 + valuesStart] << 10;
        w4 |= values[15 + valuesStart] << 29;
        w4 |= values[16 + valuesStart] << 48;
        w5 = values[16 + valuesStart] >>> 16;
        w5 |= values[17 + valuesStart] << 3;
        w5 |= values[18 + valuesStart] << 22;
        w5 |= values[19 + valuesStart] << 41;
        w5 |= values[20 + valuesStart] << 60;
        w6 = values[20 + valuesStart] >>> 4;
        w6 |= values[21 + valuesStart] << 15;
        w6 |= values[22 + valuesStart] << 34;
        w6 |= values[23 + valuesStart] << 53;
        w7 = values[23 + valuesStart] >>> 11;
        w7 |= values[24 + valuesStart] << 8;
        w7 |= values[25 + valuesStart] << 27;
        w7 |= values[26 + valuesStart] << 46;
        w8 = values[26 + valuesStart] >>> 18;
        w8 |= values[27 + valuesStart] << 1;
        w8 |= values[28 + valuesStart] << 20;
        w8 |= values[29 + valuesStart] << 39;
        w8 |= values[30 + valuesStart] << 58;
        w9 = values[30 + valuesStart] >>> 6;
        w9 |= values[31 + valuesStart] << 13;
        w9 |= values[32 + valuesStart] << 32;
        w9 |= values[33 + valuesStart] << 51;
        w10 = values[33 + valuesStart] >>> 13;
        w10 |= values[34 + valuesStart] << 6;
        w10 |= values[35 + valuesStart] << 25;
        w10 |= values[36 + valuesStart] << 44;
        w10 |= values[37 + valuesStart] << 63;
        w11 = values[37 + valuesStart] >>> 1;
        w11 |= values[38 + valuesStart] << 18;
        w11 |= values[39 + valuesStart] << 37;
        w11 |= values[40 + valuesStart] << 56;
        w12 = values[40 + valuesStart] >>> 8;
        w12 |= values[41 + valuesStart] << 11;
        w12 |= values[42 + valuesStart] << 30;
        w12 |= values[43 + valuesStart] << 49;
        w13 = values[43 + valuesStart] >>> 15;
        w13 |= values[44 + valuesStart] << 4;
        w13 |= values[45 + valuesStart] << 23;
        w13 |= values[46 + valuesStart] << 42;
        w13 |= values[47 + valuesStart] << 61;
        w14 = values[47 + valuesStart] >>> 3;
        w14 |= values[48 + valuesStart] << 16;
        w14 |= values[49 + valuesStart] << 35;
        w14 |= values[50 + valuesStart] << 54;
        w15 = values[50 + valuesStart] >>> 10;
        w15 |= values[51 + valuesStart] << 9;
        w15 |= values[52 + valuesStart] << 28;
        w15 |= values[53 + valuesStart] << 47;
        w16 = values[53 + valuesStart] >>> 17;
        w16 |= values[54 + valuesStart] << 2;
        w16 |= values[55 + valuesStart] << 21;
        w16 |= values[56 + valuesStart] << 40;
        w16 |= values[57 + valuesStart] << 59;
        w17 = values[57 + valuesStart] >>> 5;
        w17 |= values[58 + valuesStart] << 14;
        w17 |= values[59 + valuesStart] << 33;
        w17 |= values[60 + valuesStart] << 52;
        w18 = values[60 + valuesStart] >>> 12;
        w18 |= values[61 + valuesStart] << 7;
        w18 |= values[62 + valuesStart] << 26;
        w18 |= values[63 + valuesStart] << 45;
        // Write to 152 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        return 152 + packedPtr;
    }

    /**
     * Packs 64 20-bit values into 160 bytes, touching 20 words.
     */
    private static long pack20(long[] values, int valuesStart, long packedPtr) {
        // Touching 20 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 20;
        w0 |= values[2 + valuesStart] << 40;
        w0 |= values[3 + valuesStart] << 60;
        w1 = values[3 + valuesStart] >>> 4;
        w1 |= values[4 + valuesStart] << 16;
        w1 |= values[5 + valuesStart] << 36;
        w1 |= values[6 + valuesStart] << 56;
        w2 = values[6 + valuesStart] >>> 8;
        w2 |= values[7 + valuesStart] << 12;
        w2 |= values[8 + valuesStart] << 32;
        w2 |= values[9 + valuesStart] << 52;
        w3 = values[9 + valuesStart] >>> 12;
        w3 |= values[10 + valuesStart] << 8;
        w3 |= values[11 + valuesStart] << 28;
        w3 |= values[12 + valuesStart] << 48;
        w4 = values[12 + valuesStart] >>> 16;
        w4 |= values[13 + valuesStart] << 4;
        w4 |= values[14 + valuesStart] << 24;
        w4 |= values[15 + valuesStart] << 44;
        w5 = values[16 + valuesStart];
        w5 |= values[17 + valuesStart] << 20;
        w5 |= values[18 + valuesStart] << 40;
        w5 |= values[19 + valuesStart] << 60;
        w6 = values[19 + valuesStart] >>> 4;
        w6 |= values[20 + valuesStart] << 16;
        w6 |= values[21 + valuesStart] << 36;
        w6 |= values[22 + valuesStart] << 56;
        w7 = values[22 + valuesStart] >>> 8;
        w7 |= values[23 + valuesStart] << 12;
        w7 |= values[24 + valuesStart] << 32;
        w7 |= values[25 + valuesStart] << 52;
        w8 = values[25 + valuesStart] >>> 12;
        w8 |= values[26 + valuesStart] << 8;
        w8 |= values[27 + valuesStart] << 28;
        w8 |= values[28 + valuesStart] << 48;
        w9 = values[28 + valuesStart] >>> 16;
        w9 |= values[29 + valuesStart] << 4;
        w9 |= values[30 + valuesStart] << 24;
        w9 |= values[31 + valuesStart] << 44;
        w10 = values[32 + valuesStart];
        w10 |= values[33 + valuesStart] << 20;
        w10 |= values[34 + valuesStart] << 40;
        w10 |= values[35 + valuesStart] << 60;
        w11 = values[35 + valuesStart] >>> 4;
        w11 |= values[36 + valuesStart] << 16;
        w11 |= values[37 + valuesStart] << 36;
        w11 |= values[38 + valuesStart] << 56;
        w12 = values[38 + valuesStart] >>> 8;
        w12 |= values[39 + valuesStart] << 12;
        w12 |= values[40 + valuesStart] << 32;
        w12 |= values[41 + valuesStart] << 52;
        w13 = values[41 + valuesStart] >>> 12;
        w13 |= values[42 + valuesStart] << 8;
        w13 |= values[43 + valuesStart] << 28;
        w13 |= values[44 + valuesStart] << 48;
        w14 = values[44 + valuesStart] >>> 16;
        w14 |= values[45 + valuesStart] << 4;
        w14 |= values[46 + valuesStart] << 24;
        w14 |= values[47 + valuesStart] << 44;
        w15 = values[48 + valuesStart];
        w15 |= values[49 + valuesStart] << 20;
        w15 |= values[50 + valuesStart] << 40;
        w15 |= values[51 + valuesStart] << 60;
        w16 = values[51 + valuesStart] >>> 4;
        w16 |= values[52 + valuesStart] << 16;
        w16 |= values[53 + valuesStart] << 36;
        w16 |= values[54 + valuesStart] << 56;
        w17 = values[54 + valuesStart] >>> 8;
        w17 |= values[55 + valuesStart] << 12;
        w17 |= values[56 + valuesStart] << 32;
        w17 |= values[57 + valuesStart] << 52;
        w18 = values[57 + valuesStart] >>> 12;
        w18 |= values[58 + valuesStart] << 8;
        w18 |= values[59 + valuesStart] << 28;
        w18 |= values[60 + valuesStart] << 48;
        w19 = values[60 + valuesStart] >>> 16;
        w19 |= values[61 + valuesStart] << 4;
        w19 |= values[62 + valuesStart] << 24;
        w19 |= values[63 + valuesStart] << 44;
        // Write to 160 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        return 160 + packedPtr;
    }

    /**
     * Packs 64 21-bit values into 168 bytes, touching 21 words.
     */
    private static long pack21(long[] values, int valuesStart, long packedPtr) {
        // Touching 21 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 21;
        w0 |= values[2 + valuesStart] << 42;
        w0 |= values[3 + valuesStart] << 63;
        w1 = values[3 + valuesStart] >>> 1;
        w1 |= values[4 + valuesStart] << 20;
        w1 |= values[5 + valuesStart] << 41;
        w1 |= values[6 + valuesStart] << 62;
        w2 = values[6 + valuesStart] >>> 2;
        w2 |= values[7 + valuesStart] << 19;
        w2 |= values[8 + valuesStart] << 40;
        w2 |= values[9 + valuesStart] << 61;
        w3 = values[9 + valuesStart] >>> 3;
        w3 |= values[10 + valuesStart] << 18;
        w3 |= values[11 + valuesStart] << 39;
        w3 |= values[12 + valuesStart] << 60;
        w4 = values[12 + valuesStart] >>> 4;
        w4 |= values[13 + valuesStart] << 17;
        w4 |= values[14 + valuesStart] << 38;
        w4 |= values[15 + valuesStart] << 59;
        w5 = values[15 + valuesStart] >>> 5;
        w5 |= values[16 + valuesStart] << 16;
        w5 |= values[17 + valuesStart] << 37;
        w5 |= values[18 + valuesStart] << 58;
        w6 = values[18 + valuesStart] >>> 6;
        w6 |= values[19 + valuesStart] << 15;
        w6 |= values[20 + valuesStart] << 36;
        w6 |= values[21 + valuesStart] << 57;
        w7 = values[21 + valuesStart] >>> 7;
        w7 |= values[22 + valuesStart] << 14;
        w7 |= values[23 + valuesStart] << 35;
        w7 |= values[24 + valuesStart] << 56;
        w8 = values[24 + valuesStart] >>> 8;
        w8 |= values[25 + valuesStart] << 13;
        w8 |= values[26 + valuesStart] << 34;
        w8 |= values[27 + valuesStart] << 55;
        w9 = values[27 + valuesStart] >>> 9;
        w9 |= values[28 + valuesStart] << 12;
        w9 |= values[29 + valuesStart] << 33;
        w9 |= values[30 + valuesStart] << 54;
        w10 = values[30 + valuesStart] >>> 10;
        w10 |= values[31 + valuesStart] << 11;
        w10 |= values[32 + valuesStart] << 32;
        w10 |= values[33 + valuesStart] << 53;
        w11 = values[33 + valuesStart] >>> 11;
        w11 |= values[34 + valuesStart] << 10;
        w11 |= values[35 + valuesStart] << 31;
        w11 |= values[36 + valuesStart] << 52;
        w12 = values[36 + valuesStart] >>> 12;
        w12 |= values[37 + valuesStart] << 9;
        w12 |= values[38 + valuesStart] << 30;
        w12 |= values[39 + valuesStart] << 51;
        w13 = values[39 + valuesStart] >>> 13;
        w13 |= values[40 + valuesStart] << 8;
        w13 |= values[41 + valuesStart] << 29;
        w13 |= values[42 + valuesStart] << 50;
        w14 = values[42 + valuesStart] >>> 14;
        w14 |= values[43 + valuesStart] << 7;
        w14 |= values[44 + valuesStart] << 28;
        w14 |= values[45 + valuesStart] << 49;
        w15 = values[45 + valuesStart] >>> 15;
        w15 |= values[46 + valuesStart] << 6;
        w15 |= values[47 + valuesStart] << 27;
        w15 |= values[48 + valuesStart] << 48;
        w16 = values[48 + valuesStart] >>> 16;
        w16 |= values[49 + valuesStart] << 5;
        w16 |= values[50 + valuesStart] << 26;
        w16 |= values[51 + valuesStart] << 47;
        w17 = values[51 + valuesStart] >>> 17;
        w17 |= values[52 + valuesStart] << 4;
        w17 |= values[53 + valuesStart] << 25;
        w17 |= values[54 + valuesStart] << 46;
        w18 = values[54 + valuesStart] >>> 18;
        w18 |= values[55 + valuesStart] << 3;
        w18 |= values[56 + valuesStart] << 24;
        w18 |= values[57 + valuesStart] << 45;
        w19 = values[57 + valuesStart] >>> 19;
        w19 |= values[58 + valuesStart] << 2;
        w19 |= values[59 + valuesStart] << 23;
        w19 |= values[60 + valuesStart] << 44;
        w20 = values[60 + valuesStart] >>> 20;
        w20 |= values[61 + valuesStart] << 1;
        w20 |= values[62 + valuesStart] << 22;
        w20 |= values[63 + valuesStart] << 43;
        // Write to 168 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        return 168 + packedPtr;
    }

    /**
     * Packs 64 22-bit values into 176 bytes, touching 22 words.
     */
    private static long pack22(long[] values, int valuesStart, long packedPtr) {
        // Touching 22 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 22;
        w0 |= values[2 + valuesStart] << 44;
        w1 = values[2 + valuesStart] >>> 20;
        w1 |= values[3 + valuesStart] << 2;
        w1 |= values[4 + valuesStart] << 24;
        w1 |= values[5 + valuesStart] << 46;
        w2 = values[5 + valuesStart] >>> 18;
        w2 |= values[6 + valuesStart] << 4;
        w2 |= values[7 + valuesStart] << 26;
        w2 |= values[8 + valuesStart] << 48;
        w3 = values[8 + valuesStart] >>> 16;
        w3 |= values[9 + valuesStart] << 6;
        w3 |= values[10 + valuesStart] << 28;
        w3 |= values[11 + valuesStart] << 50;
        w4 = values[11 + valuesStart] >>> 14;
        w4 |= values[12 + valuesStart] << 8;
        w4 |= values[13 + valuesStart] << 30;
        w4 |= values[14 + valuesStart] << 52;
        w5 = values[14 + valuesStart] >>> 12;
        w5 |= values[15 + valuesStart] << 10;
        w5 |= values[16 + valuesStart] << 32;
        w5 |= values[17 + valuesStart] << 54;
        w6 = values[17 + valuesStart] >>> 10;
        w6 |= values[18 + valuesStart] << 12;
        w6 |= values[19 + valuesStart] << 34;
        w6 |= values[20 + valuesStart] << 56;
        w7 = values[20 + valuesStart] >>> 8;
        w7 |= values[21 + valuesStart] << 14;
        w7 |= values[22 + valuesStart] << 36;
        w7 |= values[23 + valuesStart] << 58;
        w8 = values[23 + valuesStart] >>> 6;
        w8 |= values[24 + valuesStart] << 16;
        w8 |= values[25 + valuesStart] << 38;
        w8 |= values[26 + valuesStart] << 60;
        w9 = values[26 + valuesStart] >>> 4;
        w9 |= values[27 + valuesStart] << 18;
        w9 |= values[28 + valuesStart] << 40;
        w9 |= values[29 + valuesStart] << 62;
        w10 = values[29 + valuesStart] >>> 2;
        w10 |= values[30 + valuesStart] << 20;
        w10 |= values[31 + valuesStart] << 42;
        w11 = values[32 + valuesStart];
        w11 |= values[33 + valuesStart] << 22;
        w11 |= values[34 + valuesStart] << 44;
        w12 = values[34 + valuesStart] >>> 20;
        w12 |= values[35 + valuesStart] << 2;
        w12 |= values[36 + valuesStart] << 24;
        w12 |= values[37 + valuesStart] << 46;
        w13 = values[37 + valuesStart] >>> 18;
        w13 |= values[38 + valuesStart] << 4;
        w13 |= values[39 + valuesStart] << 26;
        w13 |= values[40 + valuesStart] << 48;
        w14 = values[40 + valuesStart] >>> 16;
        w14 |= values[41 + valuesStart] << 6;
        w14 |= values[42 + valuesStart] << 28;
        w14 |= values[43 + valuesStart] << 50;
        w15 = values[43 + valuesStart] >>> 14;
        w15 |= values[44 + valuesStart] << 8;
        w15 |= values[45 + valuesStart] << 30;
        w15 |= values[46 + valuesStart] << 52;
        w16 = values[46 + valuesStart] >>> 12;
        w16 |= values[47 + valuesStart] << 10;
        w16 |= values[48 + valuesStart] << 32;
        w16 |= values[49 + valuesStart] << 54;
        w17 = values[49 + valuesStart] >>> 10;
        w17 |= values[50 + valuesStart] << 12;
        w17 |= values[51 + valuesStart] << 34;
        w17 |= values[52 + valuesStart] << 56;
        w18 = values[52 + valuesStart] >>> 8;
        w18 |= values[53 + valuesStart] << 14;
        w18 |= values[54 + valuesStart] << 36;
        w18 |= values[55 + valuesStart] << 58;
        w19 = values[55 + valuesStart] >>> 6;
        w19 |= values[56 + valuesStart] << 16;
        w19 |= values[57 + valuesStart] << 38;
        w19 |= values[58 + valuesStart] << 60;
        w20 = values[58 + valuesStart] >>> 4;
        w20 |= values[59 + valuesStart] << 18;
        w20 |= values[60 + valuesStart] << 40;
        w20 |= values[61 + valuesStart] << 62;
        w21 = values[61 + valuesStart] >>> 2;
        w21 |= values[62 + valuesStart] << 20;
        w21 |= values[63 + valuesStart] << 42;
        // Write to 176 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        return 176 + packedPtr;
    }

    /**
     * Packs 64 23-bit values into 184 bytes, touching 23 words.
     */
    private static long pack23(long[] values, int valuesStart, long packedPtr) {
        // Touching 23 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 23;
        w0 |= values[2 + valuesStart] << 46;
        w1 = values[2 + valuesStart] >>> 18;
        w1 |= values[3 + valuesStart] << 5;
        w1 |= values[4 + valuesStart] << 28;
        w1 |= values[5 + valuesStart] << 51;
        w2 = values[5 + valuesStart] >>> 13;
        w2 |= values[6 + valuesStart] << 10;
        w2 |= values[7 + valuesStart] << 33;
        w2 |= values[8 + valuesStart] << 56;
        w3 = values[8 + valuesStart] >>> 8;
        w3 |= values[9 + valuesStart] << 15;
        w3 |= values[10 + valuesStart] << 38;
        w3 |= values[11 + valuesStart] << 61;
        w4 = values[11 + valuesStart] >>> 3;
        w4 |= values[12 + valuesStart] << 20;
        w4 |= values[13 + valuesStart] << 43;
        w5 = values[13 + valuesStart] >>> 21;
        w5 |= values[14 + valuesStart] << 2;
        w5 |= values[15 + valuesStart] << 25;
        w5 |= values[16 + valuesStart] << 48;
        w6 = values[16 + valuesStart] >>> 16;
        w6 |= values[17 + valuesStart] << 7;
        w6 |= values[18 + valuesStart] << 30;
        w6 |= values[19 + valuesStart] << 53;
        w7 = values[19 + valuesStart] >>> 11;
        w7 |= values[20 + valuesStart] << 12;
        w7 |= values[21 + valuesStart] << 35;
        w7 |= values[22 + valuesStart] << 58;
        w8 = values[22 + valuesStart] >>> 6;
        w8 |= values[23 + valuesStart] << 17;
        w8 |= values[24 + valuesStart] << 40;
        w8 |= values[25 + valuesStart] << 63;
        w9 = values[25 + valuesStart] >>> 1;
        w9 |= values[26 + valuesStart] << 22;
        w9 |= values[27 + valuesStart] << 45;
        w10 = values[27 + valuesStart] >>> 19;
        w10 |= values[28 + valuesStart] << 4;
        w10 |= values[29 + valuesStart] << 27;
        w10 |= values[30 + valuesStart] << 50;
        w11 = values[30 + valuesStart] >>> 14;
        w11 |= values[31 + valuesStart] << 9;
        w11 |= values[32 + valuesStart] << 32;
        w11 |= values[33 + valuesStart] << 55;
        w12 = values[33 + valuesStart] >>> 9;
        w12 |= values[34 + valuesStart] << 14;
        w12 |= values[35 + valuesStart] << 37;
        w12 |= values[36 + valuesStart] << 60;
        w13 = values[36 + valuesStart] >>> 4;
        w13 |= values[37 + valuesStart] << 19;
        w13 |= values[38 + valuesStart] << 42;
        w14 = values[38 + valuesStart] >>> 22;
        w14 |= values[39 + valuesStart] << 1;
        w14 |= values[40 + valuesStart] << 24;
        w14 |= values[41 + valuesStart] << 47;
        w15 = values[41 + valuesStart] >>> 17;
        w15 |= values[42 + valuesStart] << 6;
        w15 |= values[43 + valuesStart] << 29;
        w15 |= values[44 + valuesStart] << 52;
        w16 = values[44 + valuesStart] >>> 12;
        w16 |= values[45 + valuesStart] << 11;
        w16 |= values[46 + valuesStart] << 34;
        w16 |= values[47 + valuesStart] << 57;
        w17 = values[47 + valuesStart] >>> 7;
        w17 |= values[48 + valuesStart] << 16;
        w17 |= values[49 + valuesStart] << 39;
        w17 |= values[50 + valuesStart] << 62;
        w18 = values[50 + valuesStart] >>> 2;
        w18 |= values[51 + valuesStart] << 21;
        w18 |= values[52 + valuesStart] << 44;
        w19 = values[52 + valuesStart] >>> 20;
        w19 |= values[53 + valuesStart] << 3;
        w19 |= values[54 + valuesStart] << 26;
        w19 |= values[55 + valuesStart] << 49;
        w20 = values[55 + valuesStart] >>> 15;
        w20 |= values[56 + valuesStart] << 8;
        w20 |= values[57 + valuesStart] << 31;
        w20 |= values[58 + valuesStart] << 54;
        w21 = values[58 + valuesStart] >>> 10;
        w21 |= values[59 + valuesStart] << 13;
        w21 |= values[60 + valuesStart] << 36;
        w21 |= values[61 + valuesStart] << 59;
        w22 = values[61 + valuesStart] >>> 5;
        w22 |= values[62 + valuesStart] << 18;
        w22 |= values[63 + valuesStart] << 41;
        // Write to 184 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        return 184 + packedPtr;
    }

    /**
     * Packs 64 24-bit values into 192 bytes, touching 24 words.
     */
    private static long pack24(long[] values, int valuesStart, long packedPtr) {
        // Touching 24 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 24;
        w0 |= values[2 + valuesStart] << 48;
        w1 = values[2 + valuesStart] >>> 16;
        w1 |= values[3 + valuesStart] << 8;
        w1 |= values[4 + valuesStart] << 32;
        w1 |= values[5 + valuesStart] << 56;
        w2 = values[5 + valuesStart] >>> 8;
        w2 |= values[6 + valuesStart] << 16;
        w2 |= values[7 + valuesStart] << 40;
        w3 = values[8 + valuesStart];
        w3 |= values[9 + valuesStart] << 24;
        w3 |= values[10 + valuesStart] << 48;
        w4 = values[10 + valuesStart] >>> 16;
        w4 |= values[11 + valuesStart] << 8;
        w4 |= values[12 + valuesStart] << 32;
        w4 |= values[13 + valuesStart] << 56;
        w5 = values[13 + valuesStart] >>> 8;
        w5 |= values[14 + valuesStart] << 16;
        w5 |= values[15 + valuesStart] << 40;
        w6 = values[16 + valuesStart];
        w6 |= values[17 + valuesStart] << 24;
        w6 |= values[18 + valuesStart] << 48;
        w7 = values[18 + valuesStart] >>> 16;
        w7 |= values[19 + valuesStart] << 8;
        w7 |= values[20 + valuesStart] << 32;
        w7 |= values[21 + valuesStart] << 56;
        w8 = values[21 + valuesStart] >>> 8;
        w8 |= values[22 + valuesStart] << 16;
        w8 |= values[23 + valuesStart] << 40;
        w9 = values[24 + valuesStart];
        w9 |= values[25 + valuesStart] << 24;
        w9 |= values[26 + valuesStart] << 48;
        w10 = values[26 + valuesStart] >>> 16;
        w10 |= values[27 + valuesStart] << 8;
        w10 |= values[28 + valuesStart] << 32;
        w10 |= values[29 + valuesStart] << 56;
        w11 = values[29 + valuesStart] >>> 8;
        w11 |= values[30 + valuesStart] << 16;
        w11 |= values[31 + valuesStart] << 40;
        w12 = values[32 + valuesStart];
        w12 |= values[33 + valuesStart] << 24;
        w12 |= values[34 + valuesStart] << 48;
        w13 = values[34 + valuesStart] >>> 16;
        w13 |= values[35 + valuesStart] << 8;
        w13 |= values[36 + valuesStart] << 32;
        w13 |= values[37 + valuesStart] << 56;
        w14 = values[37 + valuesStart] >>> 8;
        w14 |= values[38 + valuesStart] << 16;
        w14 |= values[39 + valuesStart] << 40;
        w15 = values[40 + valuesStart];
        w15 |= values[41 + valuesStart] << 24;
        w15 |= values[42 + valuesStart] << 48;
        w16 = values[42 + valuesStart] >>> 16;
        w16 |= values[43 + valuesStart] << 8;
        w16 |= values[44 + valuesStart] << 32;
        w16 |= values[45 + valuesStart] << 56;
        w17 = values[45 + valuesStart] >>> 8;
        w17 |= values[46 + valuesStart] << 16;
        w17 |= values[47 + valuesStart] << 40;
        w18 = values[48 + valuesStart];
        w18 |= values[49 + valuesStart] << 24;
        w18 |= values[50 + valuesStart] << 48;
        w19 = values[50 + valuesStart] >>> 16;
        w19 |= values[51 + valuesStart] << 8;
        w19 |= values[52 + valuesStart] << 32;
        w19 |= values[53 + valuesStart] << 56;
        w20 = values[53 + valuesStart] >>> 8;
        w20 |= values[54 + valuesStart] << 16;
        w20 |= values[55 + valuesStart] << 40;
        w21 = values[56 + valuesStart];
        w21 |= values[57 + valuesStart] << 24;
        w21 |= values[58 + valuesStart] << 48;
        w22 = values[58 + valuesStart] >>> 16;
        w22 |= values[59 + valuesStart] << 8;
        w22 |= values[60 + valuesStart] << 32;
        w22 |= values[61 + valuesStart] << 56;
        w23 = values[61 + valuesStart] >>> 8;
        w23 |= values[62 + valuesStart] << 16;
        w23 |= values[63 + valuesStart] << 40;
        // Write to 192 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        return 192 + packedPtr;
    }

    /**
     * Packs 64 25-bit values into 200 bytes, touching 25 words.
     */
    private static long pack25(long[] values, int valuesStart, long packedPtr) {
        // Touching 25 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 25;
        w0 |= values[2 + valuesStart] << 50;
        w1 = values[2 + valuesStart] >>> 14;
        w1 |= values[3 + valuesStart] << 11;
        w1 |= values[4 + valuesStart] << 36;
        w1 |= values[5 + valuesStart] << 61;
        w2 = values[5 + valuesStart] >>> 3;
        w2 |= values[6 + valuesStart] << 22;
        w2 |= values[7 + valuesStart] << 47;
        w3 = values[7 + valuesStart] >>> 17;
        w3 |= values[8 + valuesStart] << 8;
        w3 |= values[9 + valuesStart] << 33;
        w3 |= values[10 + valuesStart] << 58;
        w4 = values[10 + valuesStart] >>> 6;
        w4 |= values[11 + valuesStart] << 19;
        w4 |= values[12 + valuesStart] << 44;
        w5 = values[12 + valuesStart] >>> 20;
        w5 |= values[13 + valuesStart] << 5;
        w5 |= values[14 + valuesStart] << 30;
        w5 |= values[15 + valuesStart] << 55;
        w6 = values[15 + valuesStart] >>> 9;
        w6 |= values[16 + valuesStart] << 16;
        w6 |= values[17 + valuesStart] << 41;
        w7 = values[17 + valuesStart] >>> 23;
        w7 |= values[18 + valuesStart] << 2;
        w7 |= values[19 + valuesStart] << 27;
        w7 |= values[20 + valuesStart] << 52;
        w8 = values[20 + valuesStart] >>> 12;
        w8 |= values[21 + valuesStart] << 13;
        w8 |= values[22 + valuesStart] << 38;
        w8 |= values[23 + valuesStart] << 63;
        w9 = values[23 + valuesStart] >>> 1;
        w9 |= values[24 + valuesStart] << 24;
        w9 |= values[25 + valuesStart] << 49;
        w10 = values[25 + valuesStart] >>> 15;
        w10 |= values[26 + valuesStart] << 10;
        w10 |= values[27 + valuesStart] << 35;
        w10 |= values[28 + valuesStart] << 60;
        w11 = values[28 + valuesStart] >>> 4;
        w11 |= values[29 + valuesStart] << 21;
        w11 |= values[30 + valuesStart] << 46;
        w12 = values[30 + valuesStart] >>> 18;
        w12 |= values[31 + valuesStart] << 7;
        w12 |= values[32 + valuesStart] << 32;
        w12 |= values[33 + valuesStart] << 57;
        w13 = values[33 + valuesStart] >>> 7;
        w13 |= values[34 + valuesStart] << 18;
        w13 |= values[35 + valuesStart] << 43;
        w14 = values[35 + valuesStart] >>> 21;
        w14 |= values[36 + valuesStart] << 4;
        w14 |= values[37 + valuesStart] << 29;
        w14 |= values[38 + valuesStart] << 54;
        w15 = values[38 + valuesStart] >>> 10;
        w15 |= values[39 + valuesStart] << 15;
        w15 |= values[40 + valuesStart] << 40;
        w16 = values[40 + valuesStart] >>> 24;
        w16 |= values[41 + valuesStart] << 1;
        w16 |= values[42 + valuesStart] << 26;
        w16 |= values[43 + valuesStart] << 51;
        w17 = values[43 + valuesStart] >>> 13;
        w17 |= values[44 + valuesStart] << 12;
        w17 |= values[45 + valuesStart] << 37;
        w17 |= values[46 + valuesStart] << 62;
        w18 = values[46 + valuesStart] >>> 2;
        w18 |= values[47 + valuesStart] << 23;
        w18 |= values[48 + valuesStart] << 48;
        w19 = values[48 + valuesStart] >>> 16;
        w19 |= values[49 + valuesStart] << 9;
        w19 |= values[50 + valuesStart] << 34;
        w19 |= values[51 + valuesStart] << 59;
        w20 = values[51 + valuesStart] >>> 5;
        w20 |= values[52 + valuesStart] << 20;
        w20 |= values[53 + valuesStart] << 45;
        w21 = values[53 + valuesStart] >>> 19;
        w21 |= values[54 + valuesStart] << 6;
        w21 |= values[55 + valuesStart] << 31;
        w21 |= values[56 + valuesStart] << 56;
        w22 = values[56 + valuesStart] >>> 8;
        w22 |= values[57 + valuesStart] << 17;
        w22 |= values[58 + valuesStart] << 42;
        w23 = values[58 + valuesStart] >>> 22;
        w23 |= values[59 + valuesStart] << 3;
        w23 |= values[60 + valuesStart] << 28;
        w23 |= values[61 + valuesStart] << 53;
        w24 = values[61 + valuesStart] >>> 11;
        w24 |= values[62 + valuesStart] << 14;
        w24 |= values[63 + valuesStart] << 39;
        // Write to 200 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        return 200 + packedPtr;
    }

    /**
     * Packs 64 26-bit values into 208 bytes, touching 26 words.
     */
    private static long pack26(long[] values, int valuesStart, long packedPtr) {
        // Touching 26 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 26;
        w0 |= values[2 + valuesStart] << 52;
        w1 = values[2 + valuesStart] >>> 12;
        w1 |= values[3 + valuesStart] << 14;
        w1 |= values[4 + valuesStart] << 40;
        w2 = values[4 + valuesStart] >>> 24;
        w2 |= values[5 + valuesStart] << 2;
        w2 |= values[6 + valuesStart] << 28;
        w2 |= values[7 + valuesStart] << 54;
        w3 = values[7 + valuesStart] >>> 10;
        w3 |= values[8 + valuesStart] << 16;
        w3 |= values[9 + valuesStart] << 42;
        w4 = values[9 + valuesStart] >>> 22;
        w4 |= values[10 + valuesStart] << 4;
        w4 |= values[11 + valuesStart] << 30;
        w4 |= values[12 + valuesStart] << 56;
        w5 = values[12 + valuesStart] >>> 8;
        w5 |= values[13 + valuesStart] << 18;
        w5 |= values[14 + valuesStart] << 44;
        w6 = values[14 + valuesStart] >>> 20;
        w6 |= values[15 + valuesStart] << 6;
        w6 |= values[16 + valuesStart] << 32;
        w6 |= values[17 + valuesStart] << 58;
        w7 = values[17 + valuesStart] >>> 6;
        w7 |= values[18 + valuesStart] << 20;
        w7 |= values[19 + valuesStart] << 46;
        w8 = values[19 + valuesStart] >>> 18;
        w8 |= values[20 + valuesStart] << 8;
        w8 |= values[21 + valuesStart] << 34;
        w8 |= values[22 + valuesStart] << 60;
        w9 = values[22 + valuesStart] >>> 4;
        w9 |= values[23 + valuesStart] << 22;
        w9 |= values[24 + valuesStart] << 48;
        w10 = values[24 + valuesStart] >>> 16;
        w10 |= values[25 + valuesStart] << 10;
        w10 |= values[26 + valuesStart] << 36;
        w10 |= values[27 + valuesStart] << 62;
        w11 = values[27 + valuesStart] >>> 2;
        w11 |= values[28 + valuesStart] << 24;
        w11 |= values[29 + valuesStart] << 50;
        w12 = values[29 + valuesStart] >>> 14;
        w12 |= values[30 + valuesStart] << 12;
        w12 |= values[31 + valuesStart] << 38;
        w13 = values[32 + valuesStart];
        w13 |= values[33 + valuesStart] << 26;
        w13 |= values[34 + valuesStart] << 52;
        w14 = values[34 + valuesStart] >>> 12;
        w14 |= values[35 + valuesStart] << 14;
        w14 |= values[36 + valuesStart] << 40;
        w15 = values[36 + valuesStart] >>> 24;
        w15 |= values[37 + valuesStart] << 2;
        w15 |= values[38 + valuesStart] << 28;
        w15 |= values[39 + valuesStart] << 54;
        w16 = values[39 + valuesStart] >>> 10;
        w16 |= values[40 + valuesStart] << 16;
        w16 |= values[41 + valuesStart] << 42;
        w17 = values[41 + valuesStart] >>> 22;
        w17 |= values[42 + valuesStart] << 4;
        w17 |= values[43 + valuesStart] << 30;
        w17 |= values[44 + valuesStart] << 56;
        w18 = values[44 + valuesStart] >>> 8;
        w18 |= values[45 + valuesStart] << 18;
        w18 |= values[46 + valuesStart] << 44;
        w19 = values[46 + valuesStart] >>> 20;
        w19 |= values[47 + valuesStart] << 6;
        w19 |= values[48 + valuesStart] << 32;
        w19 |= values[49 + valuesStart] << 58;
        w20 = values[49 + valuesStart] >>> 6;
        w20 |= values[50 + valuesStart] << 20;
        w20 |= values[51 + valuesStart] << 46;
        w21 = values[51 + valuesStart] >>> 18;
        w21 |= values[52 + valuesStart] << 8;
        w21 |= values[53 + valuesStart] << 34;
        w21 |= values[54 + valuesStart] << 60;
        w22 = values[54 + valuesStart] >>> 4;
        w22 |= values[55 + valuesStart] << 22;
        w22 |= values[56 + valuesStart] << 48;
        w23 = values[56 + valuesStart] >>> 16;
        w23 |= values[57 + valuesStart] << 10;
        w23 |= values[58 + valuesStart] << 36;
        w23 |= values[59 + valuesStart] << 62;
        w24 = values[59 + valuesStart] >>> 2;
        w24 |= values[60 + valuesStart] << 24;
        w24 |= values[61 + valuesStart] << 50;
        w25 = values[61 + valuesStart] >>> 14;
        w25 |= values[62 + valuesStart] << 12;
        w25 |= values[63 + valuesStart] << 38;
        // Write to 208 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        return 208 + packedPtr;
    }

    /**
     * Packs 64 27-bit values into 216 bytes, touching 27 words.
     */
    private static long pack27(long[] values, int valuesStart, long packedPtr) {
        // Touching 27 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 27;
        w0 |= values[2 + valuesStart] << 54;
        w1 = values[2 + valuesStart] >>> 10;
        w1 |= values[3 + valuesStart] << 17;
        w1 |= values[4 + valuesStart] << 44;
        w2 = values[4 + valuesStart] >>> 20;
        w2 |= values[5 + valuesStart] << 7;
        w2 |= values[6 + valuesStart] << 34;
        w2 |= values[7 + valuesStart] << 61;
        w3 = values[7 + valuesStart] >>> 3;
        w3 |= values[8 + valuesStart] << 24;
        w3 |= values[9 + valuesStart] << 51;
        w4 = values[9 + valuesStart] >>> 13;
        w4 |= values[10 + valuesStart] << 14;
        w4 |= values[11 + valuesStart] << 41;
        w5 = values[11 + valuesStart] >>> 23;
        w5 |= values[12 + valuesStart] << 4;
        w5 |= values[13 + valuesStart] << 31;
        w5 |= values[14 + valuesStart] << 58;
        w6 = values[14 + valuesStart] >>> 6;
        w6 |= values[15 + valuesStart] << 21;
        w6 |= values[16 + valuesStart] << 48;
        w7 = values[16 + valuesStart] >>> 16;
        w7 |= values[17 + valuesStart] << 11;
        w7 |= values[18 + valuesStart] << 38;
        w8 = values[18 + valuesStart] >>> 26;
        w8 |= values[19 + valuesStart] << 1;
        w8 |= values[20 + valuesStart] << 28;
        w8 |= values[21 + valuesStart] << 55;
        w9 = values[21 + valuesStart] >>> 9;
        w9 |= values[22 + valuesStart] << 18;
        w9 |= values[23 + valuesStart] << 45;
        w10 = values[23 + valuesStart] >>> 19;
        w10 |= values[24 + valuesStart] << 8;
        w10 |= values[25 + valuesStart] << 35;
        w10 |= values[26 + valuesStart] << 62;
        w11 = values[26 + valuesStart] >>> 2;
        w11 |= values[27 + valuesStart] << 25;
        w11 |= values[28 + valuesStart] << 52;
        w12 = values[28 + valuesStart] >>> 12;
        w12 |= values[29 + valuesStart] << 15;
        w12 |= values[30 + valuesStart] << 42;
        w13 = values[30 + valuesStart] >>> 22;
        w13 |= values[31 + valuesStart] << 5;
        w13 |= values[32 + valuesStart] << 32;
        w13 |= values[33 + valuesStart] << 59;
        w14 = values[33 + valuesStart] >>> 5;
        w14 |= values[34 + valuesStart] << 22;
        w14 |= values[35 + valuesStart] << 49;
        w15 = values[35 + valuesStart] >>> 15;
        w15 |= values[36 + valuesStart] << 12;
        w15 |= values[37 + valuesStart] << 39;
        w16 = values[37 + valuesStart] >>> 25;
        w16 |= values[38 + valuesStart] << 2;
        w16 |= values[39 + valuesStart] << 29;
        w16 |= values[40 + valuesStart] << 56;
        w17 = values[40 + valuesStart] >>> 8;
        w17 |= values[41 + valuesStart] << 19;
        w17 |= values[42 + valuesStart] << 46;
        w18 = values[42 + valuesStart] >>> 18;
        w18 |= values[43 + valuesStart] << 9;
        w18 |= values[44 + valuesStart] << 36;
        w18 |= values[45 + valuesStart] << 63;
        w19 = values[45 + valuesStart] >>> 1;
        w19 |= values[46 + valuesStart] << 26;
        w19 |= values[47 + valuesStart] << 53;
        w20 = values[47 + valuesStart] >>> 11;
        w20 |= values[48 + valuesStart] << 16;
        w20 |= values[49 + valuesStart] << 43;
        w21 = values[49 + valuesStart] >>> 21;
        w21 |= values[50 + valuesStart] << 6;
        w21 |= values[51 + valuesStart] << 33;
        w21 |= values[52 + valuesStart] << 60;
        w22 = values[52 + valuesStart] >>> 4;
        w22 |= values[53 + valuesStart] << 23;
        w22 |= values[54 + valuesStart] << 50;
        w23 = values[54 + valuesStart] >>> 14;
        w23 |= values[55 + valuesStart] << 13;
        w23 |= values[56 + valuesStart] << 40;
        w24 = values[56 + valuesStart] >>> 24;
        w24 |= values[57 + valuesStart] << 3;
        w24 |= values[58 + valuesStart] << 30;
        w24 |= values[59 + valuesStart] << 57;
        w25 = values[59 + valuesStart] >>> 7;
        w25 |= values[60 + valuesStart] << 20;
        w25 |= values[61 + valuesStart] << 47;
        w26 = values[61 + valuesStart] >>> 17;
        w26 |= values[62 + valuesStart] << 10;
        w26 |= values[63 + valuesStart] << 37;
        // Write to 216 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        return 216 + packedPtr;
    }

    /**
     * Packs 64 28-bit values into 224 bytes, touching 28 words.
     */
    private static long pack28(long[] values, int valuesStart, long packedPtr) {
        // Touching 28 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 28;
        w0 |= values[2 + valuesStart] << 56;
        w1 = values[2 + valuesStart] >>> 8;
        w1 |= values[3 + valuesStart] << 20;
        w1 |= values[4 + valuesStart] << 48;
        w2 = values[4 + valuesStart] >>> 16;
        w2 |= values[5 + valuesStart] << 12;
        w2 |= values[6 + valuesStart] << 40;
        w3 = values[6 + valuesStart] >>> 24;
        w3 |= values[7 + valuesStart] << 4;
        w3 |= values[8 + valuesStart] << 32;
        w3 |= values[9 + valuesStart] << 60;
        w4 = values[9 + valuesStart] >>> 4;
        w4 |= values[10 + valuesStart] << 24;
        w4 |= values[11 + valuesStart] << 52;
        w5 = values[11 + valuesStart] >>> 12;
        w5 |= values[12 + valuesStart] << 16;
        w5 |= values[13 + valuesStart] << 44;
        w6 = values[13 + valuesStart] >>> 20;
        w6 |= values[14 + valuesStart] << 8;
        w6 |= values[15 + valuesStart] << 36;
        w7 = values[16 + valuesStart];
        w7 |= values[17 + valuesStart] << 28;
        w7 |= values[18 + valuesStart] << 56;
        w8 = values[18 + valuesStart] >>> 8;
        w8 |= values[19 + valuesStart] << 20;
        w8 |= values[20 + valuesStart] << 48;
        w9 = values[20 + valuesStart] >>> 16;
        w9 |= values[21 + valuesStart] << 12;
        w9 |= values[22 + valuesStart] << 40;
        w10 = values[22 + valuesStart] >>> 24;
        w10 |= values[23 + valuesStart] << 4;
        w10 |= values[24 + valuesStart] << 32;
        w10 |= values[25 + valuesStart] << 60;
        w11 = values[25 + valuesStart] >>> 4;
        w11 |= values[26 + valuesStart] << 24;
        w11 |= values[27 + valuesStart] << 52;
        w12 = values[27 + valuesStart] >>> 12;
        w12 |= values[28 + valuesStart] << 16;
        w12 |= values[29 + valuesStart] << 44;
        w13 = values[29 + valuesStart] >>> 20;
        w13 |= values[30 + valuesStart] << 8;
        w13 |= values[31 + valuesStart] << 36;
        w14 = values[32 + valuesStart];
        w14 |= values[33 + valuesStart] << 28;
        w14 |= values[34 + valuesStart] << 56;
        w15 = values[34 + valuesStart] >>> 8;
        w15 |= values[35 + valuesStart] << 20;
        w15 |= values[36 + valuesStart] << 48;
        w16 = values[36 + valuesStart] >>> 16;
        w16 |= values[37 + valuesStart] << 12;
        w16 |= values[38 + valuesStart] << 40;
        w17 = values[38 + valuesStart] >>> 24;
        w17 |= values[39 + valuesStart] << 4;
        w17 |= values[40 + valuesStart] << 32;
        w17 |= values[41 + valuesStart] << 60;
        w18 = values[41 + valuesStart] >>> 4;
        w18 |= values[42 + valuesStart] << 24;
        w18 |= values[43 + valuesStart] << 52;
        w19 = values[43 + valuesStart] >>> 12;
        w19 |= values[44 + valuesStart] << 16;
        w19 |= values[45 + valuesStart] << 44;
        w20 = values[45 + valuesStart] >>> 20;
        w20 |= values[46 + valuesStart] << 8;
        w20 |= values[47 + valuesStart] << 36;
        w21 = values[48 + valuesStart];
        w21 |= values[49 + valuesStart] << 28;
        w21 |= values[50 + valuesStart] << 56;
        w22 = values[50 + valuesStart] >>> 8;
        w22 |= values[51 + valuesStart] << 20;
        w22 |= values[52 + valuesStart] << 48;
        w23 = values[52 + valuesStart] >>> 16;
        w23 |= values[53 + valuesStart] << 12;
        w23 |= values[54 + valuesStart] << 40;
        w24 = values[54 + valuesStart] >>> 24;
        w24 |= values[55 + valuesStart] << 4;
        w24 |= values[56 + valuesStart] << 32;
        w24 |= values[57 + valuesStart] << 60;
        w25 = values[57 + valuesStart] >>> 4;
        w25 |= values[58 + valuesStart] << 24;
        w25 |= values[59 + valuesStart] << 52;
        w26 = values[59 + valuesStart] >>> 12;
        w26 |= values[60 + valuesStart] << 16;
        w26 |= values[61 + valuesStart] << 44;
        w27 = values[61 + valuesStart] >>> 20;
        w27 |= values[62 + valuesStart] << 8;
        w27 |= values[63 + valuesStart] << 36;
        // Write to 224 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        return 224 + packedPtr;
    }

    /**
     * Packs 64 29-bit values into 232 bytes, touching 29 words.
     */
    private static long pack29(long[] values, int valuesStart, long packedPtr) {
        // Touching 29 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 29;
        w0 |= values[2 + valuesStart] << 58;
        w1 = values[2 + valuesStart] >>> 6;
        w1 |= values[3 + valuesStart] << 23;
        w1 |= values[4 + valuesStart] << 52;
        w2 = values[4 + valuesStart] >>> 12;
        w2 |= values[5 + valuesStart] << 17;
        w2 |= values[6 + valuesStart] << 46;
        w3 = values[6 + valuesStart] >>> 18;
        w3 |= values[7 + valuesStart] << 11;
        w3 |= values[8 + valuesStart] << 40;
        w4 = values[8 + valuesStart] >>> 24;
        w4 |= values[9 + valuesStart] << 5;
        w4 |= values[10 + valuesStart] << 34;
        w4 |= values[11 + valuesStart] << 63;
        w5 = values[11 + valuesStart] >>> 1;
        w5 |= values[12 + valuesStart] << 28;
        w5 |= values[13 + valuesStart] << 57;
        w6 = values[13 + valuesStart] >>> 7;
        w6 |= values[14 + valuesStart] << 22;
        w6 |= values[15 + valuesStart] << 51;
        w7 = values[15 + valuesStart] >>> 13;
        w7 |= values[16 + valuesStart] << 16;
        w7 |= values[17 + valuesStart] << 45;
        w8 = values[17 + valuesStart] >>> 19;
        w8 |= values[18 + valuesStart] << 10;
        w8 |= values[19 + valuesStart] << 39;
        w9 = values[19 + valuesStart] >>> 25;
        w9 |= values[20 + valuesStart] << 4;
        w9 |= values[21 + valuesStart] << 33;
        w9 |= values[22 + valuesStart] << 62;
        w10 = values[22 + valuesStart] >>> 2;
        w10 |= values[23 + valuesStart] << 27;
        w10 |= values[24 + valuesStart] << 56;
        w11 = values[24 + valuesStart] >>> 8;
        w11 |= values[25 + valuesStart] << 21;
        w11 |= values[26 + valuesStart] << 50;
        w12 = values[26 + valuesStart] >>> 14;
        w12 |= values[27 + valuesStart] << 15;
        w12 |= values[28 + valuesStart] << 44;
        w13 = values[28 + valuesStart] >>> 20;
        w13 |= values[29 + valuesStart] << 9;
        w13 |= values[30 + valuesStart] << 38;
        w14 = values[30 + valuesStart] >>> 26;
        w14 |= values[31 + valuesStart] << 3;
        w14 |= values[32 + valuesStart] << 32;
        w14 |= values[33 + valuesStart] << 61;
        w15 = values[33 + valuesStart] >>> 3;
        w15 |= values[34 + valuesStart] << 26;
        w15 |= values[35 + valuesStart] << 55;
        w16 = values[35 + valuesStart] >>> 9;
        w16 |= values[36 + valuesStart] << 20;
        w16 |= values[37 + valuesStart] << 49;
        w17 = values[37 + valuesStart] >>> 15;
        w17 |= values[38 + valuesStart] << 14;
        w17 |= values[39 + valuesStart] << 43;
        w18 = values[39 + valuesStart] >>> 21;
        w18 |= values[40 + valuesStart] << 8;
        w18 |= values[41 + valuesStart] << 37;
        w19 = values[41 + valuesStart] >>> 27;
        w19 |= values[42 + valuesStart] << 2;
        w19 |= values[43 + valuesStart] << 31;
        w19 |= values[44 + valuesStart] << 60;
        w20 = values[44 + valuesStart] >>> 4;
        w20 |= values[45 + valuesStart] << 25;
        w20 |= values[46 + valuesStart] << 54;
        w21 = values[46 + valuesStart] >>> 10;
        w21 |= values[47 + valuesStart] << 19;
        w21 |= values[48 + valuesStart] << 48;
        w22 = values[48 + valuesStart] >>> 16;
        w22 |= values[49 + valuesStart] << 13;
        w22 |= values[50 + valuesStart] << 42;
        w23 = values[50 + valuesStart] >>> 22;
        w23 |= values[51 + valuesStart] << 7;
        w23 |= values[52 + valuesStart] << 36;
        w24 = values[52 + valuesStart] >>> 28;
        w24 |= values[53 + valuesStart] << 1;
        w24 |= values[54 + valuesStart] << 30;
        w24 |= values[55 + valuesStart] << 59;
        w25 = values[55 + valuesStart] >>> 5;
        w25 |= values[56 + valuesStart] << 24;
        w25 |= values[57 + valuesStart] << 53;
        w26 = values[57 + valuesStart] >>> 11;
        w26 |= values[58 + valuesStart] << 18;
        w26 |= values[59 + valuesStart] << 47;
        w27 = values[59 + valuesStart] >>> 17;
        w27 |= values[60 + valuesStart] << 12;
        w27 |= values[61 + valuesStart] << 41;
        w28 = values[61 + valuesStart] >>> 23;
        w28 |= values[62 + valuesStart] << 6;
        w28 |= values[63 + valuesStart] << 35;
        // Write to 232 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        return 232 + packedPtr;
    }

    /**
     * Packs 64 30-bit values into 240 bytes, touching 30 words.
     */
    private static long pack30(long[] values, int valuesStart, long packedPtr) {
        // Touching 30 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 30;
        w0 |= values[2 + valuesStart] << 60;
        w1 = values[2 + valuesStart] >>> 4;
        w1 |= values[3 + valuesStart] << 26;
        w1 |= values[4 + valuesStart] << 56;
        w2 = values[4 + valuesStart] >>> 8;
        w2 |= values[5 + valuesStart] << 22;
        w2 |= values[6 + valuesStart] << 52;
        w3 = values[6 + valuesStart] >>> 12;
        w3 |= values[7 + valuesStart] << 18;
        w3 |= values[8 + valuesStart] << 48;
        w4 = values[8 + valuesStart] >>> 16;
        w4 |= values[9 + valuesStart] << 14;
        w4 |= values[10 + valuesStart] << 44;
        w5 = values[10 + valuesStart] >>> 20;
        w5 |= values[11 + valuesStart] << 10;
        w5 |= values[12 + valuesStart] << 40;
        w6 = values[12 + valuesStart] >>> 24;
        w6 |= values[13 + valuesStart] << 6;
        w6 |= values[14 + valuesStart] << 36;
        w7 = values[14 + valuesStart] >>> 28;
        w7 |= values[15 + valuesStart] << 2;
        w7 |= values[16 + valuesStart] << 32;
        w7 |= values[17 + valuesStart] << 62;
        w8 = values[17 + valuesStart] >>> 2;
        w8 |= values[18 + valuesStart] << 28;
        w8 |= values[19 + valuesStart] << 58;
        w9 = values[19 + valuesStart] >>> 6;
        w9 |= values[20 + valuesStart] << 24;
        w9 |= values[21 + valuesStart] << 54;
        w10 = values[21 + valuesStart] >>> 10;
        w10 |= values[22 + valuesStart] << 20;
        w10 |= values[23 + valuesStart] << 50;
        w11 = values[23 + valuesStart] >>> 14;
        w11 |= values[24 + valuesStart] << 16;
        w11 |= values[25 + valuesStart] << 46;
        w12 = values[25 + valuesStart] >>> 18;
        w12 |= values[26 + valuesStart] << 12;
        w12 |= values[27 + valuesStart] << 42;
        w13 = values[27 + valuesStart] >>> 22;
        w13 |= values[28 + valuesStart] << 8;
        w13 |= values[29 + valuesStart] << 38;
        w14 = values[29 + valuesStart] >>> 26;
        w14 |= values[30 + valuesStart] << 4;
        w14 |= values[31 + valuesStart] << 34;
        w15 = values[32 + valuesStart];
        w15 |= values[33 + valuesStart] << 30;
        w15 |= values[34 + valuesStart] << 60;
        w16 = values[34 + valuesStart] >>> 4;
        w16 |= values[35 + valuesStart] << 26;
        w16 |= values[36 + valuesStart] << 56;
        w17 = values[36 + valuesStart] >>> 8;
        w17 |= values[37 + valuesStart] << 22;
        w17 |= values[38 + valuesStart] << 52;
        w18 = values[38 + valuesStart] >>> 12;
        w18 |= values[39 + valuesStart] << 18;
        w18 |= values[40 + valuesStart] << 48;
        w19 = values[40 + valuesStart] >>> 16;
        w19 |= values[41 + valuesStart] << 14;
        w19 |= values[42 + valuesStart] << 44;
        w20 = values[42 + valuesStart] >>> 20;
        w20 |= values[43 + valuesStart] << 10;
        w20 |= values[44 + valuesStart] << 40;
        w21 = values[44 + valuesStart] >>> 24;
        w21 |= values[45 + valuesStart] << 6;
        w21 |= values[46 + valuesStart] << 36;
        w22 = values[46 + valuesStart] >>> 28;
        w22 |= values[47 + valuesStart] << 2;
        w22 |= values[48 + valuesStart] << 32;
        w22 |= values[49 + valuesStart] << 62;
        w23 = values[49 + valuesStart] >>> 2;
        w23 |= values[50 + valuesStart] << 28;
        w23 |= values[51 + valuesStart] << 58;
        w24 = values[51 + valuesStart] >>> 6;
        w24 |= values[52 + valuesStart] << 24;
        w24 |= values[53 + valuesStart] << 54;
        w25 = values[53 + valuesStart] >>> 10;
        w25 |= values[54 + valuesStart] << 20;
        w25 |= values[55 + valuesStart] << 50;
        w26 = values[55 + valuesStart] >>> 14;
        w26 |= values[56 + valuesStart] << 16;
        w26 |= values[57 + valuesStart] << 46;
        w27 = values[57 + valuesStart] >>> 18;
        w27 |= values[58 + valuesStart] << 12;
        w27 |= values[59 + valuesStart] << 42;
        w28 = values[59 + valuesStart] >>> 22;
        w28 |= values[60 + valuesStart] << 8;
        w28 |= values[61 + valuesStart] << 38;
        w29 = values[61 + valuesStart] >>> 26;
        w29 |= values[62 + valuesStart] << 4;
        w29 |= values[63 + valuesStart] << 34;
        // Write to 240 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        return 240 + packedPtr;
    }

    /**
     * Packs 64 31-bit values into 248 bytes, touching 31 words.
     */
    private static long pack31(long[] values, int valuesStart, long packedPtr) {
        // Touching 31 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 31;
        w0 |= values[2 + valuesStart] << 62;
        w1 = values[2 + valuesStart] >>> 2;
        w1 |= values[3 + valuesStart] << 29;
        w1 |= values[4 + valuesStart] << 60;
        w2 = values[4 + valuesStart] >>> 4;
        w2 |= values[5 + valuesStart] << 27;
        w2 |= values[6 + valuesStart] << 58;
        w3 = values[6 + valuesStart] >>> 6;
        w3 |= values[7 + valuesStart] << 25;
        w3 |= values[8 + valuesStart] << 56;
        w4 = values[8 + valuesStart] >>> 8;
        w4 |= values[9 + valuesStart] << 23;
        w4 |= values[10 + valuesStart] << 54;
        w5 = values[10 + valuesStart] >>> 10;
        w5 |= values[11 + valuesStart] << 21;
        w5 |= values[12 + valuesStart] << 52;
        w6 = values[12 + valuesStart] >>> 12;
        w6 |= values[13 + valuesStart] << 19;
        w6 |= values[14 + valuesStart] << 50;
        w7 = values[14 + valuesStart] >>> 14;
        w7 |= values[15 + valuesStart] << 17;
        w7 |= values[16 + valuesStart] << 48;
        w8 = values[16 + valuesStart] >>> 16;
        w8 |= values[17 + valuesStart] << 15;
        w8 |= values[18 + valuesStart] << 46;
        w9 = values[18 + valuesStart] >>> 18;
        w9 |= values[19 + valuesStart] << 13;
        w9 |= values[20 + valuesStart] << 44;
        w10 = values[20 + valuesStart] >>> 20;
        w10 |= values[21 + valuesStart] << 11;
        w10 |= values[22 + valuesStart] << 42;
        w11 = values[22 + valuesStart] >>> 22;
        w11 |= values[23 + valuesStart] << 9;
        w11 |= values[24 + valuesStart] << 40;
        w12 = values[24 + valuesStart] >>> 24;
        w12 |= values[25 + valuesStart] << 7;
        w12 |= values[26 + valuesStart] << 38;
        w13 = values[26 + valuesStart] >>> 26;
        w13 |= values[27 + valuesStart] << 5;
        w13 |= values[28 + valuesStart] << 36;
        w14 = values[28 + valuesStart] >>> 28;
        w14 |= values[29 + valuesStart] << 3;
        w14 |= values[30 + valuesStart] << 34;
        w15 = values[30 + valuesStart] >>> 30;
        w15 |= values[31 + valuesStart] << 1;
        w15 |= values[32 + valuesStart] << 32;
        w15 |= values[33 + valuesStart] << 63;
        w16 = values[33 + valuesStart] >>> 1;
        w16 |= values[34 + valuesStart] << 30;
        w16 |= values[35 + valuesStart] << 61;
        w17 = values[35 + valuesStart] >>> 3;
        w17 |= values[36 + valuesStart] << 28;
        w17 |= values[37 + valuesStart] << 59;
        w18 = values[37 + valuesStart] >>> 5;
        w18 |= values[38 + valuesStart] << 26;
        w18 |= values[39 + valuesStart] << 57;
        w19 = values[39 + valuesStart] >>> 7;
        w19 |= values[40 + valuesStart] << 24;
        w19 |= values[41 + valuesStart] << 55;
        w20 = values[41 + valuesStart] >>> 9;
        w20 |= values[42 + valuesStart] << 22;
        w20 |= values[43 + valuesStart] << 53;
        w21 = values[43 + valuesStart] >>> 11;
        w21 |= values[44 + valuesStart] << 20;
        w21 |= values[45 + valuesStart] << 51;
        w22 = values[45 + valuesStart] >>> 13;
        w22 |= values[46 + valuesStart] << 18;
        w22 |= values[47 + valuesStart] << 49;
        w23 = values[47 + valuesStart] >>> 15;
        w23 |= values[48 + valuesStart] << 16;
        w23 |= values[49 + valuesStart] << 47;
        w24 = values[49 + valuesStart] >>> 17;
        w24 |= values[50 + valuesStart] << 14;
        w24 |= values[51 + valuesStart] << 45;
        w25 = values[51 + valuesStart] >>> 19;
        w25 |= values[52 + valuesStart] << 12;
        w25 |= values[53 + valuesStart] << 43;
        w26 = values[53 + valuesStart] >>> 21;
        w26 |= values[54 + valuesStart] << 10;
        w26 |= values[55 + valuesStart] << 41;
        w27 = values[55 + valuesStart] >>> 23;
        w27 |= values[56 + valuesStart] << 8;
        w27 |= values[57 + valuesStart] << 39;
        w28 = values[57 + valuesStart] >>> 25;
        w28 |= values[58 + valuesStart] << 6;
        w28 |= values[59 + valuesStart] << 37;
        w29 = values[59 + valuesStart] >>> 27;
        w29 |= values[60 + valuesStart] << 4;
        w29 |= values[61 + valuesStart] << 35;
        w30 = values[61 + valuesStart] >>> 29;
        w30 |= values[62 + valuesStart] << 2;
        w30 |= values[63 + valuesStart] << 33;
        // Write to 248 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        return 248 + packedPtr;
    }

    /**
     * Packs 64 32-bit values into 256 bytes, touching 32 words.
     */
    private static long pack32(long[] values, int valuesStart, long packedPtr) {
        // Touching 32 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 32;
        w1 = values[2 + valuesStart];
        w1 |= values[3 + valuesStart] << 32;
        w2 = values[4 + valuesStart];
        w2 |= values[5 + valuesStart] << 32;
        w3 = values[6 + valuesStart];
        w3 |= values[7 + valuesStart] << 32;
        w4 = values[8 + valuesStart];
        w4 |= values[9 + valuesStart] << 32;
        w5 = values[10 + valuesStart];
        w5 |= values[11 + valuesStart] << 32;
        w6 = values[12 + valuesStart];
        w6 |= values[13 + valuesStart] << 32;
        w7 = values[14 + valuesStart];
        w7 |= values[15 + valuesStart] << 32;
        w8 = values[16 + valuesStart];
        w8 |= values[17 + valuesStart] << 32;
        w9 = values[18 + valuesStart];
        w9 |= values[19 + valuesStart] << 32;
        w10 = values[20 + valuesStart];
        w10 |= values[21 + valuesStart] << 32;
        w11 = values[22 + valuesStart];
        w11 |= values[23 + valuesStart] << 32;
        w12 = values[24 + valuesStart];
        w12 |= values[25 + valuesStart] << 32;
        w13 = values[26 + valuesStart];
        w13 |= values[27 + valuesStart] << 32;
        w14 = values[28 + valuesStart];
        w14 |= values[29 + valuesStart] << 32;
        w15 = values[30 + valuesStart];
        w15 |= values[31 + valuesStart] << 32;
        w16 = values[32 + valuesStart];
        w16 |= values[33 + valuesStart] << 32;
        w17 = values[34 + valuesStart];
        w17 |= values[35 + valuesStart] << 32;
        w18 = values[36 + valuesStart];
        w18 |= values[37 + valuesStart] << 32;
        w19 = values[38 + valuesStart];
        w19 |= values[39 + valuesStart] << 32;
        w20 = values[40 + valuesStart];
        w20 |= values[41 + valuesStart] << 32;
        w21 = values[42 + valuesStart];
        w21 |= values[43 + valuesStart] << 32;
        w22 = values[44 + valuesStart];
        w22 |= values[45 + valuesStart] << 32;
        w23 = values[46 + valuesStart];
        w23 |= values[47 + valuesStart] << 32;
        w24 = values[48 + valuesStart];
        w24 |= values[49 + valuesStart] << 32;
        w25 = values[50 + valuesStart];
        w25 |= values[51 + valuesStart] << 32;
        w26 = values[52 + valuesStart];
        w26 |= values[53 + valuesStart] << 32;
        w27 = values[54 + valuesStart];
        w27 |= values[55 + valuesStart] << 32;
        w28 = values[56 + valuesStart];
        w28 |= values[57 + valuesStart] << 32;
        w29 = values[58 + valuesStart];
        w29 |= values[59 + valuesStart] << 32;
        w30 = values[60 + valuesStart];
        w30 |= values[61 + valuesStart] << 32;
        w31 = values[62 + valuesStart];
        w31 |= values[63 + valuesStart] << 32;
        // Write to 256 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        return 256 + packedPtr;
    }

    /**
     * Packs 64 33-bit values into 264 bytes, touching 33 words.
     */
    private static long pack33(long[] values, int valuesStart, long packedPtr) {
        // Touching 33 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 33;
        w1 = values[1 + valuesStart] >>> 31;
        w1 |= values[2 + valuesStart] << 2;
        w1 |= values[3 + valuesStart] << 35;
        w2 = values[3 + valuesStart] >>> 29;
        w2 |= values[4 + valuesStart] << 4;
        w2 |= values[5 + valuesStart] << 37;
        w3 = values[5 + valuesStart] >>> 27;
        w3 |= values[6 + valuesStart] << 6;
        w3 |= values[7 + valuesStart] << 39;
        w4 = values[7 + valuesStart] >>> 25;
        w4 |= values[8 + valuesStart] << 8;
        w4 |= values[9 + valuesStart] << 41;
        w5 = values[9 + valuesStart] >>> 23;
        w5 |= values[10 + valuesStart] << 10;
        w5 |= values[11 + valuesStart] << 43;
        w6 = values[11 + valuesStart] >>> 21;
        w6 |= values[12 + valuesStart] << 12;
        w6 |= values[13 + valuesStart] << 45;
        w7 = values[13 + valuesStart] >>> 19;
        w7 |= values[14 + valuesStart] << 14;
        w7 |= values[15 + valuesStart] << 47;
        w8 = values[15 + valuesStart] >>> 17;
        w8 |= values[16 + valuesStart] << 16;
        w8 |= values[17 + valuesStart] << 49;
        w9 = values[17 + valuesStart] >>> 15;
        w9 |= values[18 + valuesStart] << 18;
        w9 |= values[19 + valuesStart] << 51;
        w10 = values[19 + valuesStart] >>> 13;
        w10 |= values[20 + valuesStart] << 20;
        w10 |= values[21 + valuesStart] << 53;
        w11 = values[21 + valuesStart] >>> 11;
        w11 |= values[22 + valuesStart] << 22;
        w11 |= values[23 + valuesStart] << 55;
        w12 = values[23 + valuesStart] >>> 9;
        w12 |= values[24 + valuesStart] << 24;
        w12 |= values[25 + valuesStart] << 57;
        w13 = values[25 + valuesStart] >>> 7;
        w13 |= values[26 + valuesStart] << 26;
        w13 |= values[27 + valuesStart] << 59;
        w14 = values[27 + valuesStart] >>> 5;
        w14 |= values[28 + valuesStart] << 28;
        w14 |= values[29 + valuesStart] << 61;
        w15 = values[29 + valuesStart] >>> 3;
        w15 |= values[30 + valuesStart] << 30;
        w15 |= values[31 + valuesStart] << 63;
        w16 = values[31 + valuesStart] >>> 1;
        w16 |= values[32 + valuesStart] << 32;
        w17 = values[32 + valuesStart] >>> 32;
        w17 |= values[33 + valuesStart] << 1;
        w17 |= values[34 + valuesStart] << 34;
        w18 = values[34 + valuesStart] >>> 30;
        w18 |= values[35 + valuesStart] << 3;
        w18 |= values[36 + valuesStart] << 36;
        w19 = values[36 + valuesStart] >>> 28;
        w19 |= values[37 + valuesStart] << 5;
        w19 |= values[38 + valuesStart] << 38;
        w20 = values[38 + valuesStart] >>> 26;
        w20 |= values[39 + valuesStart] << 7;
        w20 |= values[40 + valuesStart] << 40;
        w21 = values[40 + valuesStart] >>> 24;
        w21 |= values[41 + valuesStart] << 9;
        w21 |= values[42 + valuesStart] << 42;
        w22 = values[42 + valuesStart] >>> 22;
        w22 |= values[43 + valuesStart] << 11;
        w22 |= values[44 + valuesStart] << 44;
        w23 = values[44 + valuesStart] >>> 20;
        w23 |= values[45 + valuesStart] << 13;
        w23 |= values[46 + valuesStart] << 46;
        w24 = values[46 + valuesStart] >>> 18;
        w24 |= values[47 + valuesStart] << 15;
        w24 |= values[48 + valuesStart] << 48;
        w25 = values[48 + valuesStart] >>> 16;
        w25 |= values[49 + valuesStart] << 17;
        w25 |= values[50 + valuesStart] << 50;
        w26 = values[50 + valuesStart] >>> 14;
        w26 |= values[51 + valuesStart] << 19;
        w26 |= values[52 + valuesStart] << 52;
        w27 = values[52 + valuesStart] >>> 12;
        w27 |= values[53 + valuesStart] << 21;
        w27 |= values[54 + valuesStart] << 54;
        w28 = values[54 + valuesStart] >>> 10;
        w28 |= values[55 + valuesStart] << 23;
        w28 |= values[56 + valuesStart] << 56;
        w29 = values[56 + valuesStart] >>> 8;
        w29 |= values[57 + valuesStart] << 25;
        w29 |= values[58 + valuesStart] << 58;
        w30 = values[58 + valuesStart] >>> 6;
        w30 |= values[59 + valuesStart] << 27;
        w30 |= values[60 + valuesStart] << 60;
        w31 = values[60 + valuesStart] >>> 4;
        w31 |= values[61 + valuesStart] << 29;
        w31 |= values[62 + valuesStart] << 62;
        w32 = values[62 + valuesStart] >>> 2;
        w32 |= values[63 + valuesStart] << 31;
        // Write to 264 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        return 264 + packedPtr;
    }

    /**
     * Packs 64 34-bit values into 272 bytes, touching 34 words.
     */
    private static long pack34(long[] values, int valuesStart, long packedPtr) {
        // Touching 34 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 34;
        w1 = values[1 + valuesStart] >>> 30;
        w1 |= values[2 + valuesStart] << 4;
        w1 |= values[3 + valuesStart] << 38;
        w2 = values[3 + valuesStart] >>> 26;
        w2 |= values[4 + valuesStart] << 8;
        w2 |= values[5 + valuesStart] << 42;
        w3 = values[5 + valuesStart] >>> 22;
        w3 |= values[6 + valuesStart] << 12;
        w3 |= values[7 + valuesStart] << 46;
        w4 = values[7 + valuesStart] >>> 18;
        w4 |= values[8 + valuesStart] << 16;
        w4 |= values[9 + valuesStart] << 50;
        w5 = values[9 + valuesStart] >>> 14;
        w5 |= values[10 + valuesStart] << 20;
        w5 |= values[11 + valuesStart] << 54;
        w6 = values[11 + valuesStart] >>> 10;
        w6 |= values[12 + valuesStart] << 24;
        w6 |= values[13 + valuesStart] << 58;
        w7 = values[13 + valuesStart] >>> 6;
        w7 |= values[14 + valuesStart] << 28;
        w7 |= values[15 + valuesStart] << 62;
        w8 = values[15 + valuesStart] >>> 2;
        w8 |= values[16 + valuesStart] << 32;
        w9 = values[16 + valuesStart] >>> 32;
        w9 |= values[17 + valuesStart] << 2;
        w9 |= values[18 + valuesStart] << 36;
        w10 = values[18 + valuesStart] >>> 28;
        w10 |= values[19 + valuesStart] << 6;
        w10 |= values[20 + valuesStart] << 40;
        w11 = values[20 + valuesStart] >>> 24;
        w11 |= values[21 + valuesStart] << 10;
        w11 |= values[22 + valuesStart] << 44;
        w12 = values[22 + valuesStart] >>> 20;
        w12 |= values[23 + valuesStart] << 14;
        w12 |= values[24 + valuesStart] << 48;
        w13 = values[24 + valuesStart] >>> 16;
        w13 |= values[25 + valuesStart] << 18;
        w13 |= values[26 + valuesStart] << 52;
        w14 = values[26 + valuesStart] >>> 12;
        w14 |= values[27 + valuesStart] << 22;
        w14 |= values[28 + valuesStart] << 56;
        w15 = values[28 + valuesStart] >>> 8;
        w15 |= values[29 + valuesStart] << 26;
        w15 |= values[30 + valuesStart] << 60;
        w16 = values[30 + valuesStart] >>> 4;
        w16 |= values[31 + valuesStart] << 30;
        w17 = values[32 + valuesStart];
        w17 |= values[33 + valuesStart] << 34;
        w18 = values[33 + valuesStart] >>> 30;
        w18 |= values[34 + valuesStart] << 4;
        w18 |= values[35 + valuesStart] << 38;
        w19 = values[35 + valuesStart] >>> 26;
        w19 |= values[36 + valuesStart] << 8;
        w19 |= values[37 + valuesStart] << 42;
        w20 = values[37 + valuesStart] >>> 22;
        w20 |= values[38 + valuesStart] << 12;
        w20 |= values[39 + valuesStart] << 46;
        w21 = values[39 + valuesStart] >>> 18;
        w21 |= values[40 + valuesStart] << 16;
        w21 |= values[41 + valuesStart] << 50;
        w22 = values[41 + valuesStart] >>> 14;
        w22 |= values[42 + valuesStart] << 20;
        w22 |= values[43 + valuesStart] << 54;
        w23 = values[43 + valuesStart] >>> 10;
        w23 |= values[44 + valuesStart] << 24;
        w23 |= values[45 + valuesStart] << 58;
        w24 = values[45 + valuesStart] >>> 6;
        w24 |= values[46 + valuesStart] << 28;
        w24 |= values[47 + valuesStart] << 62;
        w25 = values[47 + valuesStart] >>> 2;
        w25 |= values[48 + valuesStart] << 32;
        w26 = values[48 + valuesStart] >>> 32;
        w26 |= values[49 + valuesStart] << 2;
        w26 |= values[50 + valuesStart] << 36;
        w27 = values[50 + valuesStart] >>> 28;
        w27 |= values[51 + valuesStart] << 6;
        w27 |= values[52 + valuesStart] << 40;
        w28 = values[52 + valuesStart] >>> 24;
        w28 |= values[53 + valuesStart] << 10;
        w28 |= values[54 + valuesStart] << 44;
        w29 = values[54 + valuesStart] >>> 20;
        w29 |= values[55 + valuesStart] << 14;
        w29 |= values[56 + valuesStart] << 48;
        w30 = values[56 + valuesStart] >>> 16;
        w30 |= values[57 + valuesStart] << 18;
        w30 |= values[58 + valuesStart] << 52;
        w31 = values[58 + valuesStart] >>> 12;
        w31 |= values[59 + valuesStart] << 22;
        w31 |= values[60 + valuesStart] << 56;
        w32 = values[60 + valuesStart] >>> 8;
        w32 |= values[61 + valuesStart] << 26;
        w32 |= values[62 + valuesStart] << 60;
        w33 = values[62 + valuesStart] >>> 4;
        w33 |= values[63 + valuesStart] << 30;
        // Write to 272 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        return 272 + packedPtr;
    }

    /**
     * Packs 64 35-bit values into 280 bytes, touching 35 words.
     */
    private static long pack35(long[] values, int valuesStart, long packedPtr) {
        // Touching 35 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 35;
        w1 = values[1 + valuesStart] >>> 29;
        w1 |= values[2 + valuesStart] << 6;
        w1 |= values[3 + valuesStart] << 41;
        w2 = values[3 + valuesStart] >>> 23;
        w2 |= values[4 + valuesStart] << 12;
        w2 |= values[5 + valuesStart] << 47;
        w3 = values[5 + valuesStart] >>> 17;
        w3 |= values[6 + valuesStart] << 18;
        w3 |= values[7 + valuesStart] << 53;
        w4 = values[7 + valuesStart] >>> 11;
        w4 |= values[8 + valuesStart] << 24;
        w4 |= values[9 + valuesStart] << 59;
        w5 = values[9 + valuesStart] >>> 5;
        w5 |= values[10 + valuesStart] << 30;
        w6 = values[10 + valuesStart] >>> 34;
        w6 |= values[11 + valuesStart] << 1;
        w6 |= values[12 + valuesStart] << 36;
        w7 = values[12 + valuesStart] >>> 28;
        w7 |= values[13 + valuesStart] << 7;
        w7 |= values[14 + valuesStart] << 42;
        w8 = values[14 + valuesStart] >>> 22;
        w8 |= values[15 + valuesStart] << 13;
        w8 |= values[16 + valuesStart] << 48;
        w9 = values[16 + valuesStart] >>> 16;
        w9 |= values[17 + valuesStart] << 19;
        w9 |= values[18 + valuesStart] << 54;
        w10 = values[18 + valuesStart] >>> 10;
        w10 |= values[19 + valuesStart] << 25;
        w10 |= values[20 + valuesStart] << 60;
        w11 = values[20 + valuesStart] >>> 4;
        w11 |= values[21 + valuesStart] << 31;
        w12 = values[21 + valuesStart] >>> 33;
        w12 |= values[22 + valuesStart] << 2;
        w12 |= values[23 + valuesStart] << 37;
        w13 = values[23 + valuesStart] >>> 27;
        w13 |= values[24 + valuesStart] << 8;
        w13 |= values[25 + valuesStart] << 43;
        w14 = values[25 + valuesStart] >>> 21;
        w14 |= values[26 + valuesStart] << 14;
        w14 |= values[27 + valuesStart] << 49;
        w15 = values[27 + valuesStart] >>> 15;
        w15 |= values[28 + valuesStart] << 20;
        w15 |= values[29 + valuesStart] << 55;
        w16 = values[29 + valuesStart] >>> 9;
        w16 |= values[30 + valuesStart] << 26;
        w16 |= values[31 + valuesStart] << 61;
        w17 = values[31 + valuesStart] >>> 3;
        w17 |= values[32 + valuesStart] << 32;
        w18 = values[32 + valuesStart] >>> 32;
        w18 |= values[33 + valuesStart] << 3;
        w18 |= values[34 + valuesStart] << 38;
        w19 = values[34 + valuesStart] >>> 26;
        w19 |= values[35 + valuesStart] << 9;
        w19 |= values[36 + valuesStart] << 44;
        w20 = values[36 + valuesStart] >>> 20;
        w20 |= values[37 + valuesStart] << 15;
        w20 |= values[38 + valuesStart] << 50;
        w21 = values[38 + valuesStart] >>> 14;
        w21 |= values[39 + valuesStart] << 21;
        w21 |= values[40 + valuesStart] << 56;
        w22 = values[40 + valuesStart] >>> 8;
        w22 |= values[41 + valuesStart] << 27;
        w22 |= values[42 + valuesStart] << 62;
        w23 = values[42 + valuesStart] >>> 2;
        w23 |= values[43 + valuesStart] << 33;
        w24 = values[43 + valuesStart] >>> 31;
        w24 |= values[44 + valuesStart] << 4;
        w24 |= values[45 + valuesStart] << 39;
        w25 = values[45 + valuesStart] >>> 25;
        w25 |= values[46 + valuesStart] << 10;
        w25 |= values[47 + valuesStart] << 45;
        w26 = values[47 + valuesStart] >>> 19;
        w26 |= values[48 + valuesStart] << 16;
        w26 |= values[49 + valuesStart] << 51;
        w27 = values[49 + valuesStart] >>> 13;
        w27 |= values[50 + valuesStart] << 22;
        w27 |= values[51 + valuesStart] << 57;
        w28 = values[51 + valuesStart] >>> 7;
        w28 |= values[52 + valuesStart] << 28;
        w28 |= values[53 + valuesStart] << 63;
        w29 = values[53 + valuesStart] >>> 1;
        w29 |= values[54 + valuesStart] << 34;
        w30 = values[54 + valuesStart] >>> 30;
        w30 |= values[55 + valuesStart] << 5;
        w30 |= values[56 + valuesStart] << 40;
        w31 = values[56 + valuesStart] >>> 24;
        w31 |= values[57 + valuesStart] << 11;
        w31 |= values[58 + valuesStart] << 46;
        w32 = values[58 + valuesStart] >>> 18;
        w32 |= values[59 + valuesStart] << 17;
        w32 |= values[60 + valuesStart] << 52;
        w33 = values[60 + valuesStart] >>> 12;
        w33 |= values[61 + valuesStart] << 23;
        w33 |= values[62 + valuesStart] << 58;
        w34 = values[62 + valuesStart] >>> 6;
        w34 |= values[63 + valuesStart] << 29;
        // Write to 280 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        return 280 + packedPtr;
    }

    /**
     * Packs 64 36-bit values into 288 bytes, touching 36 words.
     */
    private static long pack36(long[] values, int valuesStart, long packedPtr) {
        // Touching 36 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 36;
        w1 = values[1 + valuesStart] >>> 28;
        w1 |= values[2 + valuesStart] << 8;
        w1 |= values[3 + valuesStart] << 44;
        w2 = values[3 + valuesStart] >>> 20;
        w2 |= values[4 + valuesStart] << 16;
        w2 |= values[5 + valuesStart] << 52;
        w3 = values[5 + valuesStart] >>> 12;
        w3 |= values[6 + valuesStart] << 24;
        w3 |= values[7 + valuesStart] << 60;
        w4 = values[7 + valuesStart] >>> 4;
        w4 |= values[8 + valuesStart] << 32;
        w5 = values[8 + valuesStart] >>> 32;
        w5 |= values[9 + valuesStart] << 4;
        w5 |= values[10 + valuesStart] << 40;
        w6 = values[10 + valuesStart] >>> 24;
        w6 |= values[11 + valuesStart] << 12;
        w6 |= values[12 + valuesStart] << 48;
        w7 = values[12 + valuesStart] >>> 16;
        w7 |= values[13 + valuesStart] << 20;
        w7 |= values[14 + valuesStart] << 56;
        w8 = values[14 + valuesStart] >>> 8;
        w8 |= values[15 + valuesStart] << 28;
        w9 = values[16 + valuesStart];
        w9 |= values[17 + valuesStart] << 36;
        w10 = values[17 + valuesStart] >>> 28;
        w10 |= values[18 + valuesStart] << 8;
        w10 |= values[19 + valuesStart] << 44;
        w11 = values[19 + valuesStart] >>> 20;
        w11 |= values[20 + valuesStart] << 16;
        w11 |= values[21 + valuesStart] << 52;
        w12 = values[21 + valuesStart] >>> 12;
        w12 |= values[22 + valuesStart] << 24;
        w12 |= values[23 + valuesStart] << 60;
        w13 = values[23 + valuesStart] >>> 4;
        w13 |= values[24 + valuesStart] << 32;
        w14 = values[24 + valuesStart] >>> 32;
        w14 |= values[25 + valuesStart] << 4;
        w14 |= values[26 + valuesStart] << 40;
        w15 = values[26 + valuesStart] >>> 24;
        w15 |= values[27 + valuesStart] << 12;
        w15 |= values[28 + valuesStart] << 48;
        w16 = values[28 + valuesStart] >>> 16;
        w16 |= values[29 + valuesStart] << 20;
        w16 |= values[30 + valuesStart] << 56;
        w17 = values[30 + valuesStart] >>> 8;
        w17 |= values[31 + valuesStart] << 28;
        w18 = values[32 + valuesStart];
        w18 |= values[33 + valuesStart] << 36;
        w19 = values[33 + valuesStart] >>> 28;
        w19 |= values[34 + valuesStart] << 8;
        w19 |= values[35 + valuesStart] << 44;
        w20 = values[35 + valuesStart] >>> 20;
        w20 |= values[36 + valuesStart] << 16;
        w20 |= values[37 + valuesStart] << 52;
        w21 = values[37 + valuesStart] >>> 12;
        w21 |= values[38 + valuesStart] << 24;
        w21 |= values[39 + valuesStart] << 60;
        w22 = values[39 + valuesStart] >>> 4;
        w22 |= values[40 + valuesStart] << 32;
        w23 = values[40 + valuesStart] >>> 32;
        w23 |= values[41 + valuesStart] << 4;
        w23 |= values[42 + valuesStart] << 40;
        w24 = values[42 + valuesStart] >>> 24;
        w24 |= values[43 + valuesStart] << 12;
        w24 |= values[44 + valuesStart] << 48;
        w25 = values[44 + valuesStart] >>> 16;
        w25 |= values[45 + valuesStart] << 20;
        w25 |= values[46 + valuesStart] << 56;
        w26 = values[46 + valuesStart] >>> 8;
        w26 |= values[47 + valuesStart] << 28;
        w27 = values[48 + valuesStart];
        w27 |= values[49 + valuesStart] << 36;
        w28 = values[49 + valuesStart] >>> 28;
        w28 |= values[50 + valuesStart] << 8;
        w28 |= values[51 + valuesStart] << 44;
        w29 = values[51 + valuesStart] >>> 20;
        w29 |= values[52 + valuesStart] << 16;
        w29 |= values[53 + valuesStart] << 52;
        w30 = values[53 + valuesStart] >>> 12;
        w30 |= values[54 + valuesStart] << 24;
        w30 |= values[55 + valuesStart] << 60;
        w31 = values[55 + valuesStart] >>> 4;
        w31 |= values[56 + valuesStart] << 32;
        w32 = values[56 + valuesStart] >>> 32;
        w32 |= values[57 + valuesStart] << 4;
        w32 |= values[58 + valuesStart] << 40;
        w33 = values[58 + valuesStart] >>> 24;
        w33 |= values[59 + valuesStart] << 12;
        w33 |= values[60 + valuesStart] << 48;
        w34 = values[60 + valuesStart] >>> 16;
        w34 |= values[61 + valuesStart] << 20;
        w34 |= values[62 + valuesStart] << 56;
        w35 = values[62 + valuesStart] >>> 8;
        w35 |= values[63 + valuesStart] << 28;
        // Write to 288 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        return 288 + packedPtr;
    }

    /**
     * Packs 64 37-bit values into 296 bytes, touching 37 words.
     */
    private static long pack37(long[] values, int valuesStart, long packedPtr) {
        // Touching 37 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 37;
        w1 = values[1 + valuesStart] >>> 27;
        w1 |= values[2 + valuesStart] << 10;
        w1 |= values[3 + valuesStart] << 47;
        w2 = values[3 + valuesStart] >>> 17;
        w2 |= values[4 + valuesStart] << 20;
        w2 |= values[5 + valuesStart] << 57;
        w3 = values[5 + valuesStart] >>> 7;
        w3 |= values[6 + valuesStart] << 30;
        w4 = values[6 + valuesStart] >>> 34;
        w4 |= values[7 + valuesStart] << 3;
        w4 |= values[8 + valuesStart] << 40;
        w5 = values[8 + valuesStart] >>> 24;
        w5 |= values[9 + valuesStart] << 13;
        w5 |= values[10 + valuesStart] << 50;
        w6 = values[10 + valuesStart] >>> 14;
        w6 |= values[11 + valuesStart] << 23;
        w6 |= values[12 + valuesStart] << 60;
        w7 = values[12 + valuesStart] >>> 4;
        w7 |= values[13 + valuesStart] << 33;
        w8 = values[13 + valuesStart] >>> 31;
        w8 |= values[14 + valuesStart] << 6;
        w8 |= values[15 + valuesStart] << 43;
        w9 = values[15 + valuesStart] >>> 21;
        w9 |= values[16 + valuesStart] << 16;
        w9 |= values[17 + valuesStart] << 53;
        w10 = values[17 + valuesStart] >>> 11;
        w10 |= values[18 + valuesStart] << 26;
        w10 |= values[19 + valuesStart] << 63;
        w11 = values[19 + valuesStart] >>> 1;
        w11 |= values[20 + valuesStart] << 36;
        w12 = values[20 + valuesStart] >>> 28;
        w12 |= values[21 + valuesStart] << 9;
        w12 |= values[22 + valuesStart] << 46;
        w13 = values[22 + valuesStart] >>> 18;
        w13 |= values[23 + valuesStart] << 19;
        w13 |= values[24 + valuesStart] << 56;
        w14 = values[24 + valuesStart] >>> 8;
        w14 |= values[25 + valuesStart] << 29;
        w15 = values[25 + valuesStart] >>> 35;
        w15 |= values[26 + valuesStart] << 2;
        w15 |= values[27 + valuesStart] << 39;
        w16 = values[27 + valuesStart] >>> 25;
        w16 |= values[28 + valuesStart] << 12;
        w16 |= values[29 + valuesStart] << 49;
        w17 = values[29 + valuesStart] >>> 15;
        w17 |= values[30 + valuesStart] << 22;
        w17 |= values[31 + valuesStart] << 59;
        w18 = values[31 + valuesStart] >>> 5;
        w18 |= values[32 + valuesStart] << 32;
        w19 = values[32 + valuesStart] >>> 32;
        w19 |= values[33 + valuesStart] << 5;
        w19 |= values[34 + valuesStart] << 42;
        w20 = values[34 + valuesStart] >>> 22;
        w20 |= values[35 + valuesStart] << 15;
        w20 |= values[36 + valuesStart] << 52;
        w21 = values[36 + valuesStart] >>> 12;
        w21 |= values[37 + valuesStart] << 25;
        w21 |= values[38 + valuesStart] << 62;
        w22 = values[38 + valuesStart] >>> 2;
        w22 |= values[39 + valuesStart] << 35;
        w23 = values[39 + valuesStart] >>> 29;
        w23 |= values[40 + valuesStart] << 8;
        w23 |= values[41 + valuesStart] << 45;
        w24 = values[41 + valuesStart] >>> 19;
        w24 |= values[42 + valuesStart] << 18;
        w24 |= values[43 + valuesStart] << 55;
        w25 = values[43 + valuesStart] >>> 9;
        w25 |= values[44 + valuesStart] << 28;
        w26 = values[44 + valuesStart] >>> 36;
        w26 |= values[45 + valuesStart] << 1;
        w26 |= values[46 + valuesStart] << 38;
        w27 = values[46 + valuesStart] >>> 26;
        w27 |= values[47 + valuesStart] << 11;
        w27 |= values[48 + valuesStart] << 48;
        w28 = values[48 + valuesStart] >>> 16;
        w28 |= values[49 + valuesStart] << 21;
        w28 |= values[50 + valuesStart] << 58;
        w29 = values[50 + valuesStart] >>> 6;
        w29 |= values[51 + valuesStart] << 31;
        w30 = values[51 + valuesStart] >>> 33;
        w30 |= values[52 + valuesStart] << 4;
        w30 |= values[53 + valuesStart] << 41;
        w31 = values[53 + valuesStart] >>> 23;
        w31 |= values[54 + valuesStart] << 14;
        w31 |= values[55 + valuesStart] << 51;
        w32 = values[55 + valuesStart] >>> 13;
        w32 |= values[56 + valuesStart] << 24;
        w32 |= values[57 + valuesStart] << 61;
        w33 = values[57 + valuesStart] >>> 3;
        w33 |= values[58 + valuesStart] << 34;
        w34 = values[58 + valuesStart] >>> 30;
        w34 |= values[59 + valuesStart] << 7;
        w34 |= values[60 + valuesStart] << 44;
        w35 = values[60 + valuesStart] >>> 20;
        w35 |= values[61 + valuesStart] << 17;
        w35 |= values[62 + valuesStart] << 54;
        w36 = values[62 + valuesStart] >>> 10;
        w36 |= values[63 + valuesStart] << 27;
        // Write to 296 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        return 296 + packedPtr;
    }

    /**
     * Packs 64 38-bit values into 304 bytes, touching 38 words.
     */
    private static long pack38(long[] values, int valuesStart, long packedPtr) {
        // Touching 38 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 38;
        w1 = values[1 + valuesStart] >>> 26;
        w1 |= values[2 + valuesStart] << 12;
        w1 |= values[3 + valuesStart] << 50;
        w2 = values[3 + valuesStart] >>> 14;
        w2 |= values[4 + valuesStart] << 24;
        w2 |= values[5 + valuesStart] << 62;
        w3 = values[5 + valuesStart] >>> 2;
        w3 |= values[6 + valuesStart] << 36;
        w4 = values[6 + valuesStart] >>> 28;
        w4 |= values[7 + valuesStart] << 10;
        w4 |= values[8 + valuesStart] << 48;
        w5 = values[8 + valuesStart] >>> 16;
        w5 |= values[9 + valuesStart] << 22;
        w5 |= values[10 + valuesStart] << 60;
        w6 = values[10 + valuesStart] >>> 4;
        w6 |= values[11 + valuesStart] << 34;
        w7 = values[11 + valuesStart] >>> 30;
        w7 |= values[12 + valuesStart] << 8;
        w7 |= values[13 + valuesStart] << 46;
        w8 = values[13 + valuesStart] >>> 18;
        w8 |= values[14 + valuesStart] << 20;
        w8 |= values[15 + valuesStart] << 58;
        w9 = values[15 + valuesStart] >>> 6;
        w9 |= values[16 + valuesStart] << 32;
        w10 = values[16 + valuesStart] >>> 32;
        w10 |= values[17 + valuesStart] << 6;
        w10 |= values[18 + valuesStart] << 44;
        w11 = values[18 + valuesStart] >>> 20;
        w11 |= values[19 + valuesStart] << 18;
        w11 |= values[20 + valuesStart] << 56;
        w12 = values[20 + valuesStart] >>> 8;
        w12 |= values[21 + valuesStart] << 30;
        w13 = values[21 + valuesStart] >>> 34;
        w13 |= values[22 + valuesStart] << 4;
        w13 |= values[23 + valuesStart] << 42;
        w14 = values[23 + valuesStart] >>> 22;
        w14 |= values[24 + valuesStart] << 16;
        w14 |= values[25 + valuesStart] << 54;
        w15 = values[25 + valuesStart] >>> 10;
        w15 |= values[26 + valuesStart] << 28;
        w16 = values[26 + valuesStart] >>> 36;
        w16 |= values[27 + valuesStart] << 2;
        w16 |= values[28 + valuesStart] << 40;
        w17 = values[28 + valuesStart] >>> 24;
        w17 |= values[29 + valuesStart] << 14;
        w17 |= values[30 + valuesStart] << 52;
        w18 = values[30 + valuesStart] >>> 12;
        w18 |= values[31 + valuesStart] << 26;
        w19 = values[32 + valuesStart];
        w19 |= values[33 + valuesStart] << 38;
        w20 = values[33 + valuesStart] >>> 26;
        w20 |= values[34 + valuesStart] << 12;
        w20 |= values[35 + valuesStart] << 50;
        w21 = values[35 + valuesStart] >>> 14;
        w21 |= values[36 + valuesStart] << 24;
        w21 |= values[37 + valuesStart] << 62;
        w22 = values[37 + valuesStart] >>> 2;
        w22 |= values[38 + valuesStart] << 36;
        w23 = values[38 + valuesStart] >>> 28;
        w23 |= values[39 + valuesStart] << 10;
        w23 |= values[40 + valuesStart] << 48;
        w24 = values[40 + valuesStart] >>> 16;
        w24 |= values[41 + valuesStart] << 22;
        w24 |= values[42 + valuesStart] << 60;
        w25 = values[42 + valuesStart] >>> 4;
        w25 |= values[43 + valuesStart] << 34;
        w26 = values[43 + valuesStart] >>> 30;
        w26 |= values[44 + valuesStart] << 8;
        w26 |= values[45 + valuesStart] << 46;
        w27 = values[45 + valuesStart] >>> 18;
        w27 |= values[46 + valuesStart] << 20;
        w27 |= values[47 + valuesStart] << 58;
        w28 = values[47 + valuesStart] >>> 6;
        w28 |= values[48 + valuesStart] << 32;
        w29 = values[48 + valuesStart] >>> 32;
        w29 |= values[49 + valuesStart] << 6;
        w29 |= values[50 + valuesStart] << 44;
        w30 = values[50 + valuesStart] >>> 20;
        w30 |= values[51 + valuesStart] << 18;
        w30 |= values[52 + valuesStart] << 56;
        w31 = values[52 + valuesStart] >>> 8;
        w31 |= values[53 + valuesStart] << 30;
        w32 = values[53 + valuesStart] >>> 34;
        w32 |= values[54 + valuesStart] << 4;
        w32 |= values[55 + valuesStart] << 42;
        w33 = values[55 + valuesStart] >>> 22;
        w33 |= values[56 + valuesStart] << 16;
        w33 |= values[57 + valuesStart] << 54;
        w34 = values[57 + valuesStart] >>> 10;
        w34 |= values[58 + valuesStart] << 28;
        w35 = values[58 + valuesStart] >>> 36;
        w35 |= values[59 + valuesStart] << 2;
        w35 |= values[60 + valuesStart] << 40;
        w36 = values[60 + valuesStart] >>> 24;
        w36 |= values[61 + valuesStart] << 14;
        w36 |= values[62 + valuesStart] << 52;
        w37 = values[62 + valuesStart] >>> 12;
        w37 |= values[63 + valuesStart] << 26;
        // Write to 304 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        return 304 + packedPtr;
    }

    /**
     * Packs 64 39-bit values into 312 bytes, touching 39 words.
     */
    private static long pack39(long[] values, int valuesStart, long packedPtr) {
        // Touching 39 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 39;
        w1 = values[1 + valuesStart] >>> 25;
        w1 |= values[2 + valuesStart] << 14;
        w1 |= values[3 + valuesStart] << 53;
        w2 = values[3 + valuesStart] >>> 11;
        w2 |= values[4 + valuesStart] << 28;
        w3 = values[4 + valuesStart] >>> 36;
        w3 |= values[5 + valuesStart] << 3;
        w3 |= values[6 + valuesStart] << 42;
        w4 = values[6 + valuesStart] >>> 22;
        w4 |= values[7 + valuesStart] << 17;
        w4 |= values[8 + valuesStart] << 56;
        w5 = values[8 + valuesStart] >>> 8;
        w5 |= values[9 + valuesStart] << 31;
        w6 = values[9 + valuesStart] >>> 33;
        w6 |= values[10 + valuesStart] << 6;
        w6 |= values[11 + valuesStart] << 45;
        w7 = values[11 + valuesStart] >>> 19;
        w7 |= values[12 + valuesStart] << 20;
        w7 |= values[13 + valuesStart] << 59;
        w8 = values[13 + valuesStart] >>> 5;
        w8 |= values[14 + valuesStart] << 34;
        w9 = values[14 + valuesStart] >>> 30;
        w9 |= values[15 + valuesStart] << 9;
        w9 |= values[16 + valuesStart] << 48;
        w10 = values[16 + valuesStart] >>> 16;
        w10 |= values[17 + valuesStart] << 23;
        w10 |= values[18 + valuesStart] << 62;
        w11 = values[18 + valuesStart] >>> 2;
        w11 |= values[19 + valuesStart] << 37;
        w12 = values[19 + valuesStart] >>> 27;
        w12 |= values[20 + valuesStart] << 12;
        w12 |= values[21 + valuesStart] << 51;
        w13 = values[21 + valuesStart] >>> 13;
        w13 |= values[22 + valuesStart] << 26;
        w14 = values[22 + valuesStart] >>> 38;
        w14 |= values[23 + valuesStart] << 1;
        w14 |= values[24 + valuesStart] << 40;
        w15 = values[24 + valuesStart] >>> 24;
        w15 |= values[25 + valuesStart] << 15;
        w15 |= values[26 + valuesStart] << 54;
        w16 = values[26 + valuesStart] >>> 10;
        w16 |= values[27 + valuesStart] << 29;
        w17 = values[27 + valuesStart] >>> 35;
        w17 |= values[28 + valuesStart] << 4;
        w17 |= values[29 + valuesStart] << 43;
        w18 = values[29 + valuesStart] >>> 21;
        w18 |= values[30 + valuesStart] << 18;
        w18 |= values[31 + valuesStart] << 57;
        w19 = values[31 + valuesStart] >>> 7;
        w19 |= values[32 + valuesStart] << 32;
        w20 = values[32 + valuesStart] >>> 32;
        w20 |= values[33 + valuesStart] << 7;
        w20 |= values[34 + valuesStart] << 46;
        w21 = values[34 + valuesStart] >>> 18;
        w21 |= values[35 + valuesStart] << 21;
        w21 |= values[36 + valuesStart] << 60;
        w22 = values[36 + valuesStart] >>> 4;
        w22 |= values[37 + valuesStart] << 35;
        w23 = values[37 + valuesStart] >>> 29;
        w23 |= values[38 + valuesStart] << 10;
        w23 |= values[39 + valuesStart] << 49;
        w24 = values[39 + valuesStart] >>> 15;
        w24 |= values[40 + valuesStart] << 24;
        w24 |= values[41 + valuesStart] << 63;
        w25 = values[41 + valuesStart] >>> 1;
        w25 |= values[42 + valuesStart] << 38;
        w26 = values[42 + valuesStart] >>> 26;
        w26 |= values[43 + valuesStart] << 13;
        w26 |= values[44 + valuesStart] << 52;
        w27 = values[44 + valuesStart] >>> 12;
        w27 |= values[45 + valuesStart] << 27;
        w28 = values[45 + valuesStart] >>> 37;
        w28 |= values[46 + valuesStart] << 2;
        w28 |= values[47 + valuesStart] << 41;
        w29 = values[47 + valuesStart] >>> 23;
        w29 |= values[48 + valuesStart] << 16;
        w29 |= values[49 + valuesStart] << 55;
        w30 = values[49 + valuesStart] >>> 9;
        w30 |= values[50 + valuesStart] << 30;
        w31 = values[50 + valuesStart] >>> 34;
        w31 |= values[51 + valuesStart] << 5;
        w31 |= values[52 + valuesStart] << 44;
        w32 = values[52 + valuesStart] >>> 20;
        w32 |= values[53 + valuesStart] << 19;
        w32 |= values[54 + valuesStart] << 58;
        w33 = values[54 + valuesStart] >>> 6;
        w33 |= values[55 + valuesStart] << 33;
        w34 = values[55 + valuesStart] >>> 31;
        w34 |= values[56 + valuesStart] << 8;
        w34 |= values[57 + valuesStart] << 47;
        w35 = values[57 + valuesStart] >>> 17;
        w35 |= values[58 + valuesStart] << 22;
        w35 |= values[59 + valuesStart] << 61;
        w36 = values[59 + valuesStart] >>> 3;
        w36 |= values[60 + valuesStart] << 36;
        w37 = values[60 + valuesStart] >>> 28;
        w37 |= values[61 + valuesStart] << 11;
        w37 |= values[62 + valuesStart] << 50;
        w38 = values[62 + valuesStart] >>> 14;
        w38 |= values[63 + valuesStart] << 25;
        // Write to 312 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        return 312 + packedPtr;
    }

    /**
     * Packs 64 40-bit values into 320 bytes, touching 40 words.
     */
    private static long pack40(long[] values, int valuesStart, long packedPtr) {
        // Touching 40 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 40;
        w1 = values[1 + valuesStart] >>> 24;
        w1 |= values[2 + valuesStart] << 16;
        w1 |= values[3 + valuesStart] << 56;
        w2 = values[3 + valuesStart] >>> 8;
        w2 |= values[4 + valuesStart] << 32;
        w3 = values[4 + valuesStart] >>> 32;
        w3 |= values[5 + valuesStart] << 8;
        w3 |= values[6 + valuesStart] << 48;
        w4 = values[6 + valuesStart] >>> 16;
        w4 |= values[7 + valuesStart] << 24;
        w5 = values[8 + valuesStart];
        w5 |= values[9 + valuesStart] << 40;
        w6 = values[9 + valuesStart] >>> 24;
        w6 |= values[10 + valuesStart] << 16;
        w6 |= values[11 + valuesStart] << 56;
        w7 = values[11 + valuesStart] >>> 8;
        w7 |= values[12 + valuesStart] << 32;
        w8 = values[12 + valuesStart] >>> 32;
        w8 |= values[13 + valuesStart] << 8;
        w8 |= values[14 + valuesStart] << 48;
        w9 = values[14 + valuesStart] >>> 16;
        w9 |= values[15 + valuesStart] << 24;
        w10 = values[16 + valuesStart];
        w10 |= values[17 + valuesStart] << 40;
        w11 = values[17 + valuesStart] >>> 24;
        w11 |= values[18 + valuesStart] << 16;
        w11 |= values[19 + valuesStart] << 56;
        w12 = values[19 + valuesStart] >>> 8;
        w12 |= values[20 + valuesStart] << 32;
        w13 = values[20 + valuesStart] >>> 32;
        w13 |= values[21 + valuesStart] << 8;
        w13 |= values[22 + valuesStart] << 48;
        w14 = values[22 + valuesStart] >>> 16;
        w14 |= values[23 + valuesStart] << 24;
        w15 = values[24 + valuesStart];
        w15 |= values[25 + valuesStart] << 40;
        w16 = values[25 + valuesStart] >>> 24;
        w16 |= values[26 + valuesStart] << 16;
        w16 |= values[27 + valuesStart] << 56;
        w17 = values[27 + valuesStart] >>> 8;
        w17 |= values[28 + valuesStart] << 32;
        w18 = values[28 + valuesStart] >>> 32;
        w18 |= values[29 + valuesStart] << 8;
        w18 |= values[30 + valuesStart] << 48;
        w19 = values[30 + valuesStart] >>> 16;
        w19 |= values[31 + valuesStart] << 24;
        w20 = values[32 + valuesStart];
        w20 |= values[33 + valuesStart] << 40;
        w21 = values[33 + valuesStart] >>> 24;
        w21 |= values[34 + valuesStart] << 16;
        w21 |= values[35 + valuesStart] << 56;
        w22 = values[35 + valuesStart] >>> 8;
        w22 |= values[36 + valuesStart] << 32;
        w23 = values[36 + valuesStart] >>> 32;
        w23 |= values[37 + valuesStart] << 8;
        w23 |= values[38 + valuesStart] << 48;
        w24 = values[38 + valuesStart] >>> 16;
        w24 |= values[39 + valuesStart] << 24;
        w25 = values[40 + valuesStart];
        w25 |= values[41 + valuesStart] << 40;
        w26 = values[41 + valuesStart] >>> 24;
        w26 |= values[42 + valuesStart] << 16;
        w26 |= values[43 + valuesStart] << 56;
        w27 = values[43 + valuesStart] >>> 8;
        w27 |= values[44 + valuesStart] << 32;
        w28 = values[44 + valuesStart] >>> 32;
        w28 |= values[45 + valuesStart] << 8;
        w28 |= values[46 + valuesStart] << 48;
        w29 = values[46 + valuesStart] >>> 16;
        w29 |= values[47 + valuesStart] << 24;
        w30 = values[48 + valuesStart];
        w30 |= values[49 + valuesStart] << 40;
        w31 = values[49 + valuesStart] >>> 24;
        w31 |= values[50 + valuesStart] << 16;
        w31 |= values[51 + valuesStart] << 56;
        w32 = values[51 + valuesStart] >>> 8;
        w32 |= values[52 + valuesStart] << 32;
        w33 = values[52 + valuesStart] >>> 32;
        w33 |= values[53 + valuesStart] << 8;
        w33 |= values[54 + valuesStart] << 48;
        w34 = values[54 + valuesStart] >>> 16;
        w34 |= values[55 + valuesStart] << 24;
        w35 = values[56 + valuesStart];
        w35 |= values[57 + valuesStart] << 40;
        w36 = values[57 + valuesStart] >>> 24;
        w36 |= values[58 + valuesStart] << 16;
        w36 |= values[59 + valuesStart] << 56;
        w37 = values[59 + valuesStart] >>> 8;
        w37 |= values[60 + valuesStart] << 32;
        w38 = values[60 + valuesStart] >>> 32;
        w38 |= values[61 + valuesStart] << 8;
        w38 |= values[62 + valuesStart] << 48;
        w39 = values[62 + valuesStart] >>> 16;
        w39 |= values[63 + valuesStart] << 24;
        // Write to 320 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        return 320 + packedPtr;
    }

    /**
     * Packs 64 41-bit values into 328 bytes, touching 41 words.
     */
    private static long pack41(long[] values, int valuesStart, long packedPtr) {
        // Touching 41 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 41;
        w1 = values[1 + valuesStart] >>> 23;
        w1 |= values[2 + valuesStart] << 18;
        w1 |= values[3 + valuesStart] << 59;
        w2 = values[3 + valuesStart] >>> 5;
        w2 |= values[4 + valuesStart] << 36;
        w3 = values[4 + valuesStart] >>> 28;
        w3 |= values[5 + valuesStart] << 13;
        w3 |= values[6 + valuesStart] << 54;
        w4 = values[6 + valuesStart] >>> 10;
        w4 |= values[7 + valuesStart] << 31;
        w5 = values[7 + valuesStart] >>> 33;
        w5 |= values[8 + valuesStart] << 8;
        w5 |= values[9 + valuesStart] << 49;
        w6 = values[9 + valuesStart] >>> 15;
        w6 |= values[10 + valuesStart] << 26;
        w7 = values[10 + valuesStart] >>> 38;
        w7 |= values[11 + valuesStart] << 3;
        w7 |= values[12 + valuesStart] << 44;
        w8 = values[12 + valuesStart] >>> 20;
        w8 |= values[13 + valuesStart] << 21;
        w8 |= values[14 + valuesStart] << 62;
        w9 = values[14 + valuesStart] >>> 2;
        w9 |= values[15 + valuesStart] << 39;
        w10 = values[15 + valuesStart] >>> 25;
        w10 |= values[16 + valuesStart] << 16;
        w10 |= values[17 + valuesStart] << 57;
        w11 = values[17 + valuesStart] >>> 7;
        w11 |= values[18 + valuesStart] << 34;
        w12 = values[18 + valuesStart] >>> 30;
        w12 |= values[19 + valuesStart] << 11;
        w12 |= values[20 + valuesStart] << 52;
        w13 = values[20 + valuesStart] >>> 12;
        w13 |= values[21 + valuesStart] << 29;
        w14 = values[21 + valuesStart] >>> 35;
        w14 |= values[22 + valuesStart] << 6;
        w14 |= values[23 + valuesStart] << 47;
        w15 = values[23 + valuesStart] >>> 17;
        w15 |= values[24 + valuesStart] << 24;
        w16 = values[24 + valuesStart] >>> 40;
        w16 |= values[25 + valuesStart] << 1;
        w16 |= values[26 + valuesStart] << 42;
        w17 = values[26 + valuesStart] >>> 22;
        w17 |= values[27 + valuesStart] << 19;
        w17 |= values[28 + valuesStart] << 60;
        w18 = values[28 + valuesStart] >>> 4;
        w18 |= values[29 + valuesStart] << 37;
        w19 = values[29 + valuesStart] >>> 27;
        w19 |= values[30 + valuesStart] << 14;
        w19 |= values[31 + valuesStart] << 55;
        w20 = values[31 + valuesStart] >>> 9;
        w20 |= values[32 + valuesStart] << 32;
        w21 = values[32 + valuesStart] >>> 32;
        w21 |= values[33 + valuesStart] << 9;
        w21 |= values[34 + valuesStart] << 50;
        w22 = values[34 + valuesStart] >>> 14;
        w22 |= values[35 + valuesStart] << 27;
        w23 = values[35 + valuesStart] >>> 37;
        w23 |= values[36 + valuesStart] << 4;
        w23 |= values[37 + valuesStart] << 45;
        w24 = values[37 + valuesStart] >>> 19;
        w24 |= values[38 + valuesStart] << 22;
        w24 |= values[39 + valuesStart] << 63;
        w25 = values[39 + valuesStart] >>> 1;
        w25 |= values[40 + valuesStart] << 40;
        w26 = values[40 + valuesStart] >>> 24;
        w26 |= values[41 + valuesStart] << 17;
        w26 |= values[42 + valuesStart] << 58;
        w27 = values[42 + valuesStart] >>> 6;
        w27 |= values[43 + valuesStart] << 35;
        w28 = values[43 + valuesStart] >>> 29;
        w28 |= values[44 + valuesStart] << 12;
        w28 |= values[45 + valuesStart] << 53;
        w29 = values[45 + valuesStart] >>> 11;
        w29 |= values[46 + valuesStart] << 30;
        w30 = values[46 + valuesStart] >>> 34;
        w30 |= values[47 + valuesStart] << 7;
        w30 |= values[48 + valuesStart] << 48;
        w31 = values[48 + valuesStart] >>> 16;
        w31 |= values[49 + valuesStart] << 25;
        w32 = values[49 + valuesStart] >>> 39;
        w32 |= values[50 + valuesStart] << 2;
        w32 |= values[51 + valuesStart] << 43;
        w33 = values[51 + valuesStart] >>> 21;
        w33 |= values[52 + valuesStart] << 20;
        w33 |= values[53 + valuesStart] << 61;
        w34 = values[53 + valuesStart] >>> 3;
        w34 |= values[54 + valuesStart] << 38;
        w35 = values[54 + valuesStart] >>> 26;
        w35 |= values[55 + valuesStart] << 15;
        w35 |= values[56 + valuesStart] << 56;
        w36 = values[56 + valuesStart] >>> 8;
        w36 |= values[57 + valuesStart] << 33;
        w37 = values[57 + valuesStart] >>> 31;
        w37 |= values[58 + valuesStart] << 10;
        w37 |= values[59 + valuesStart] << 51;
        w38 = values[59 + valuesStart] >>> 13;
        w38 |= values[60 + valuesStart] << 28;
        w39 = values[60 + valuesStart] >>> 36;
        w39 |= values[61 + valuesStart] << 5;
        w39 |= values[62 + valuesStart] << 46;
        w40 = values[62 + valuesStart] >>> 18;
        w40 |= values[63 + valuesStart] << 23;
        // Write to 328 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        return 328 + packedPtr;
    }

    /**
     * Packs 64 42-bit values into 336 bytes, touching 42 words.
     */
    private static long pack42(long[] values, int valuesStart, long packedPtr) {
        // Touching 42 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 42;
        w1 = values[1 + valuesStart] >>> 22;
        w1 |= values[2 + valuesStart] << 20;
        w1 |= values[3 + valuesStart] << 62;
        w2 = values[3 + valuesStart] >>> 2;
        w2 |= values[4 + valuesStart] << 40;
        w3 = values[4 + valuesStart] >>> 24;
        w3 |= values[5 + valuesStart] << 18;
        w3 |= values[6 + valuesStart] << 60;
        w4 = values[6 + valuesStart] >>> 4;
        w4 |= values[7 + valuesStart] << 38;
        w5 = values[7 + valuesStart] >>> 26;
        w5 |= values[8 + valuesStart] << 16;
        w5 |= values[9 + valuesStart] << 58;
        w6 = values[9 + valuesStart] >>> 6;
        w6 |= values[10 + valuesStart] << 36;
        w7 = values[10 + valuesStart] >>> 28;
        w7 |= values[11 + valuesStart] << 14;
        w7 |= values[12 + valuesStart] << 56;
        w8 = values[12 + valuesStart] >>> 8;
        w8 |= values[13 + valuesStart] << 34;
        w9 = values[13 + valuesStart] >>> 30;
        w9 |= values[14 + valuesStart] << 12;
        w9 |= values[15 + valuesStart] << 54;
        w10 = values[15 + valuesStart] >>> 10;
        w10 |= values[16 + valuesStart] << 32;
        w11 = values[16 + valuesStart] >>> 32;
        w11 |= values[17 + valuesStart] << 10;
        w11 |= values[18 + valuesStart] << 52;
        w12 = values[18 + valuesStart] >>> 12;
        w12 |= values[19 + valuesStart] << 30;
        w13 = values[19 + valuesStart] >>> 34;
        w13 |= values[20 + valuesStart] << 8;
        w13 |= values[21 + valuesStart] << 50;
        w14 = values[21 + valuesStart] >>> 14;
        w14 |= values[22 + valuesStart] << 28;
        w15 = values[22 + valuesStart] >>> 36;
        w15 |= values[23 + valuesStart] << 6;
        w15 |= values[24 + valuesStart] << 48;
        w16 = values[24 + valuesStart] >>> 16;
        w16 |= values[25 + valuesStart] << 26;
        w17 = values[25 + valuesStart] >>> 38;
        w17 |= values[26 + valuesStart] << 4;
        w17 |= values[27 + valuesStart] << 46;
        w18 = values[27 + valuesStart] >>> 18;
        w18 |= values[28 + valuesStart] << 24;
        w19 = values[28 + valuesStart] >>> 40;
        w19 |= values[29 + valuesStart] << 2;
        w19 |= values[30 + valuesStart] << 44;
        w20 = values[30 + valuesStart] >>> 20;
        w20 |= values[31 + valuesStart] << 22;
        w21 = values[32 + valuesStart];
        w21 |= values[33 + valuesStart] << 42;
        w22 = values[33 + valuesStart] >>> 22;
        w22 |= values[34 + valuesStart] << 20;
        w22 |= values[35 + valuesStart] << 62;
        w23 = values[35 + valuesStart] >>> 2;
        w23 |= values[36 + valuesStart] << 40;
        w24 = values[36 + valuesStart] >>> 24;
        w24 |= values[37 + valuesStart] << 18;
        w24 |= values[38 + valuesStart] << 60;
        w25 = values[38 + valuesStart] >>> 4;
        w25 |= values[39 + valuesStart] << 38;
        w26 = values[39 + valuesStart] >>> 26;
        w26 |= values[40 + valuesStart] << 16;
        w26 |= values[41 + valuesStart] << 58;
        w27 = values[41 + valuesStart] >>> 6;
        w27 |= values[42 + valuesStart] << 36;
        w28 = values[42 + valuesStart] >>> 28;
        w28 |= values[43 + valuesStart] << 14;
        w28 |= values[44 + valuesStart] << 56;
        w29 = values[44 + valuesStart] >>> 8;
        w29 |= values[45 + valuesStart] << 34;
        w30 = values[45 + valuesStart] >>> 30;
        w30 |= values[46 + valuesStart] << 12;
        w30 |= values[47 + valuesStart] << 54;
        w31 = values[47 + valuesStart] >>> 10;
        w31 |= values[48 + valuesStart] << 32;
        w32 = values[48 + valuesStart] >>> 32;
        w32 |= values[49 + valuesStart] << 10;
        w32 |= values[50 + valuesStart] << 52;
        w33 = values[50 + valuesStart] >>> 12;
        w33 |= values[51 + valuesStart] << 30;
        w34 = values[51 + valuesStart] >>> 34;
        w34 |= values[52 + valuesStart] << 8;
        w34 |= values[53 + valuesStart] << 50;
        w35 = values[53 + valuesStart] >>> 14;
        w35 |= values[54 + valuesStart] << 28;
        w36 = values[54 + valuesStart] >>> 36;
        w36 |= values[55 + valuesStart] << 6;
        w36 |= values[56 + valuesStart] << 48;
        w37 = values[56 + valuesStart] >>> 16;
        w37 |= values[57 + valuesStart] << 26;
        w38 = values[57 + valuesStart] >>> 38;
        w38 |= values[58 + valuesStart] << 4;
        w38 |= values[59 + valuesStart] << 46;
        w39 = values[59 + valuesStart] >>> 18;
        w39 |= values[60 + valuesStart] << 24;
        w40 = values[60 + valuesStart] >>> 40;
        w40 |= values[61 + valuesStart] << 2;
        w40 |= values[62 + valuesStart] << 44;
        w41 = values[62 + valuesStart] >>> 20;
        w41 |= values[63 + valuesStart] << 22;
        // Write to 336 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        return 336 + packedPtr;
    }

    /**
     * Packs 64 43-bit values into 344 bytes, touching 43 words.
     */
    private static long pack43(long[] values, int valuesStart, long packedPtr) {
        // Touching 43 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 43;
        w1 = values[1 + valuesStart] >>> 21;
        w1 |= values[2 + valuesStart] << 22;
        w2 = values[2 + valuesStart] >>> 42;
        w2 |= values[3 + valuesStart] << 1;
        w2 |= values[4 + valuesStart] << 44;
        w3 = values[4 + valuesStart] >>> 20;
        w3 |= values[5 + valuesStart] << 23;
        w4 = values[5 + valuesStart] >>> 41;
        w4 |= values[6 + valuesStart] << 2;
        w4 |= values[7 + valuesStart] << 45;
        w5 = values[7 + valuesStart] >>> 19;
        w5 |= values[8 + valuesStart] << 24;
        w6 = values[8 + valuesStart] >>> 40;
        w6 |= values[9 + valuesStart] << 3;
        w6 |= values[10 + valuesStart] << 46;
        w7 = values[10 + valuesStart] >>> 18;
        w7 |= values[11 + valuesStart] << 25;
        w8 = values[11 + valuesStart] >>> 39;
        w8 |= values[12 + valuesStart] << 4;
        w8 |= values[13 + valuesStart] << 47;
        w9 = values[13 + valuesStart] >>> 17;
        w9 |= values[14 + valuesStart] << 26;
        w10 = values[14 + valuesStart] >>> 38;
        w10 |= values[15 + valuesStart] << 5;
        w10 |= values[16 + valuesStart] << 48;
        w11 = values[16 + valuesStart] >>> 16;
        w11 |= values[17 + valuesStart] << 27;
        w12 = values[17 + valuesStart] >>> 37;
        w12 |= values[18 + valuesStart] << 6;
        w12 |= values[19 + valuesStart] << 49;
        w13 = values[19 + valuesStart] >>> 15;
        w13 |= values[20 + valuesStart] << 28;
        w14 = values[20 + valuesStart] >>> 36;
        w14 |= values[21 + valuesStart] << 7;
        w14 |= values[22 + valuesStart] << 50;
        w15 = values[22 + valuesStart] >>> 14;
        w15 |= values[23 + valuesStart] << 29;
        w16 = values[23 + valuesStart] >>> 35;
        w16 |= values[24 + valuesStart] << 8;
        w16 |= values[25 + valuesStart] << 51;
        w17 = values[25 + valuesStart] >>> 13;
        w17 |= values[26 + valuesStart] << 30;
        w18 = values[26 + valuesStart] >>> 34;
        w18 |= values[27 + valuesStart] << 9;
        w18 |= values[28 + valuesStart] << 52;
        w19 = values[28 + valuesStart] >>> 12;
        w19 |= values[29 + valuesStart] << 31;
        w20 = values[29 + valuesStart] >>> 33;
        w20 |= values[30 + valuesStart] << 10;
        w20 |= values[31 + valuesStart] << 53;
        w21 = values[31 + valuesStart] >>> 11;
        w21 |= values[32 + valuesStart] << 32;
        w22 = values[32 + valuesStart] >>> 32;
        w22 |= values[33 + valuesStart] << 11;
        w22 |= values[34 + valuesStart] << 54;
        w23 = values[34 + valuesStart] >>> 10;
        w23 |= values[35 + valuesStart] << 33;
        w24 = values[35 + valuesStart] >>> 31;
        w24 |= values[36 + valuesStart] << 12;
        w24 |= values[37 + valuesStart] << 55;
        w25 = values[37 + valuesStart] >>> 9;
        w25 |= values[38 + valuesStart] << 34;
        w26 = values[38 + valuesStart] >>> 30;
        w26 |= values[39 + valuesStart] << 13;
        w26 |= values[40 + valuesStart] << 56;
        w27 = values[40 + valuesStart] >>> 8;
        w27 |= values[41 + valuesStart] << 35;
        w28 = values[41 + valuesStart] >>> 29;
        w28 |= values[42 + valuesStart] << 14;
        w28 |= values[43 + valuesStart] << 57;
        w29 = values[43 + valuesStart] >>> 7;
        w29 |= values[44 + valuesStart] << 36;
        w30 = values[44 + valuesStart] >>> 28;
        w30 |= values[45 + valuesStart] << 15;
        w30 |= values[46 + valuesStart] << 58;
        w31 = values[46 + valuesStart] >>> 6;
        w31 |= values[47 + valuesStart] << 37;
        w32 = values[47 + valuesStart] >>> 27;
        w32 |= values[48 + valuesStart] << 16;
        w32 |= values[49 + valuesStart] << 59;
        w33 = values[49 + valuesStart] >>> 5;
        w33 |= values[50 + valuesStart] << 38;
        w34 = values[50 + valuesStart] >>> 26;
        w34 |= values[51 + valuesStart] << 17;
        w34 |= values[52 + valuesStart] << 60;
        w35 = values[52 + valuesStart] >>> 4;
        w35 |= values[53 + valuesStart] << 39;
        w36 = values[53 + valuesStart] >>> 25;
        w36 |= values[54 + valuesStart] << 18;
        w36 |= values[55 + valuesStart] << 61;
        w37 = values[55 + valuesStart] >>> 3;
        w37 |= values[56 + valuesStart] << 40;
        w38 = values[56 + valuesStart] >>> 24;
        w38 |= values[57 + valuesStart] << 19;
        w38 |= values[58 + valuesStart] << 62;
        w39 = values[58 + valuesStart] >>> 2;
        w39 |= values[59 + valuesStart] << 41;
        w40 = values[59 + valuesStart] >>> 23;
        w40 |= values[60 + valuesStart] << 20;
        w40 |= values[61 + valuesStart] << 63;
        w41 = values[61 + valuesStart] >>> 1;
        w41 |= values[62 + valuesStart] << 42;
        w42 = values[62 + valuesStart] >>> 22;
        w42 |= values[63 + valuesStart] << 21;
        // Write to 344 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        return 344 + packedPtr;
    }

    /**
     * Packs 64 44-bit values into 352 bytes, touching 44 words.
     */
    private static long pack44(long[] values, int valuesStart, long packedPtr) {
        // Touching 44 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 44;
        w1 = values[1 + valuesStart] >>> 20;
        w1 |= values[2 + valuesStart] << 24;
        w2 = values[2 + valuesStart] >>> 40;
        w2 |= values[3 + valuesStart] << 4;
        w2 |= values[4 + valuesStart] << 48;
        w3 = values[4 + valuesStart] >>> 16;
        w3 |= values[5 + valuesStart] << 28;
        w4 = values[5 + valuesStart] >>> 36;
        w4 |= values[6 + valuesStart] << 8;
        w4 |= values[7 + valuesStart] << 52;
        w5 = values[7 + valuesStart] >>> 12;
        w5 |= values[8 + valuesStart] << 32;
        w6 = values[8 + valuesStart] >>> 32;
        w6 |= values[9 + valuesStart] << 12;
        w6 |= values[10 + valuesStart] << 56;
        w7 = values[10 + valuesStart] >>> 8;
        w7 |= values[11 + valuesStart] << 36;
        w8 = values[11 + valuesStart] >>> 28;
        w8 |= values[12 + valuesStart] << 16;
        w8 |= values[13 + valuesStart] << 60;
        w9 = values[13 + valuesStart] >>> 4;
        w9 |= values[14 + valuesStart] << 40;
        w10 = values[14 + valuesStart] >>> 24;
        w10 |= values[15 + valuesStart] << 20;
        w11 = values[16 + valuesStart];
        w11 |= values[17 + valuesStart] << 44;
        w12 = values[17 + valuesStart] >>> 20;
        w12 |= values[18 + valuesStart] << 24;
        w13 = values[18 + valuesStart] >>> 40;
        w13 |= values[19 + valuesStart] << 4;
        w13 |= values[20 + valuesStart] << 48;
        w14 = values[20 + valuesStart] >>> 16;
        w14 |= values[21 + valuesStart] << 28;
        w15 = values[21 + valuesStart] >>> 36;
        w15 |= values[22 + valuesStart] << 8;
        w15 |= values[23 + valuesStart] << 52;
        w16 = values[23 + valuesStart] >>> 12;
        w16 |= values[24 + valuesStart] << 32;
        w17 = values[24 + valuesStart] >>> 32;
        w17 |= values[25 + valuesStart] << 12;
        w17 |= values[26 + valuesStart] << 56;
        w18 = values[26 + valuesStart] >>> 8;
        w18 |= values[27 + valuesStart] << 36;
        w19 = values[27 + valuesStart] >>> 28;
        w19 |= values[28 + valuesStart] << 16;
        w19 |= values[29 + valuesStart] << 60;
        w20 = values[29 + valuesStart] >>> 4;
        w20 |= values[30 + valuesStart] << 40;
        w21 = values[30 + valuesStart] >>> 24;
        w21 |= values[31 + valuesStart] << 20;
        w22 = values[32 + valuesStart];
        w22 |= values[33 + valuesStart] << 44;
        w23 = values[33 + valuesStart] >>> 20;
        w23 |= values[34 + valuesStart] << 24;
        w24 = values[34 + valuesStart] >>> 40;
        w24 |= values[35 + valuesStart] << 4;
        w24 |= values[36 + valuesStart] << 48;
        w25 = values[36 + valuesStart] >>> 16;
        w25 |= values[37 + valuesStart] << 28;
        w26 = values[37 + valuesStart] >>> 36;
        w26 |= values[38 + valuesStart] << 8;
        w26 |= values[39 + valuesStart] << 52;
        w27 = values[39 + valuesStart] >>> 12;
        w27 |= values[40 + valuesStart] << 32;
        w28 = values[40 + valuesStart] >>> 32;
        w28 |= values[41 + valuesStart] << 12;
        w28 |= values[42 + valuesStart] << 56;
        w29 = values[42 + valuesStart] >>> 8;
        w29 |= values[43 + valuesStart] << 36;
        w30 = values[43 + valuesStart] >>> 28;
        w30 |= values[44 + valuesStart] << 16;
        w30 |= values[45 + valuesStart] << 60;
        w31 = values[45 + valuesStart] >>> 4;
        w31 |= values[46 + valuesStart] << 40;
        w32 = values[46 + valuesStart] >>> 24;
        w32 |= values[47 + valuesStart] << 20;
        w33 = values[48 + valuesStart];
        w33 |= values[49 + valuesStart] << 44;
        w34 = values[49 + valuesStart] >>> 20;
        w34 |= values[50 + valuesStart] << 24;
        w35 = values[50 + valuesStart] >>> 40;
        w35 |= values[51 + valuesStart] << 4;
        w35 |= values[52 + valuesStart] << 48;
        w36 = values[52 + valuesStart] >>> 16;
        w36 |= values[53 + valuesStart] << 28;
        w37 = values[53 + valuesStart] >>> 36;
        w37 |= values[54 + valuesStart] << 8;
        w37 |= values[55 + valuesStart] << 52;
        w38 = values[55 + valuesStart] >>> 12;
        w38 |= values[56 + valuesStart] << 32;
        w39 = values[56 + valuesStart] >>> 32;
        w39 |= values[57 + valuesStart] << 12;
        w39 |= values[58 + valuesStart] << 56;
        w40 = values[58 + valuesStart] >>> 8;
        w40 |= values[59 + valuesStart] << 36;
        w41 = values[59 + valuesStart] >>> 28;
        w41 |= values[60 + valuesStart] << 16;
        w41 |= values[61 + valuesStart] << 60;
        w42 = values[61 + valuesStart] >>> 4;
        w42 |= values[62 + valuesStart] << 40;
        w43 = values[62 + valuesStart] >>> 24;
        w43 |= values[63 + valuesStart] << 20;
        // Write to 352 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        return 352 + packedPtr;
    }

    /**
     * Packs 64 45-bit values into 360 bytes, touching 45 words.
     */
    private static long pack45(long[] values, int valuesStart, long packedPtr) {
        // Touching 45 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 45;
        w1 = values[1 + valuesStart] >>> 19;
        w1 |= values[2 + valuesStart] << 26;
        w2 = values[2 + valuesStart] >>> 38;
        w2 |= values[3 + valuesStart] << 7;
        w2 |= values[4 + valuesStart] << 52;
        w3 = values[4 + valuesStart] >>> 12;
        w3 |= values[5 + valuesStart] << 33;
        w4 = values[5 + valuesStart] >>> 31;
        w4 |= values[6 + valuesStart] << 14;
        w4 |= values[7 + valuesStart] << 59;
        w5 = values[7 + valuesStart] >>> 5;
        w5 |= values[8 + valuesStart] << 40;
        w6 = values[8 + valuesStart] >>> 24;
        w6 |= values[9 + valuesStart] << 21;
        w7 = values[9 + valuesStart] >>> 43;
        w7 |= values[10 + valuesStart] << 2;
        w7 |= values[11 + valuesStart] << 47;
        w8 = values[11 + valuesStart] >>> 17;
        w8 |= values[12 + valuesStart] << 28;
        w9 = values[12 + valuesStart] >>> 36;
        w9 |= values[13 + valuesStart] << 9;
        w9 |= values[14 + valuesStart] << 54;
        w10 = values[14 + valuesStart] >>> 10;
        w10 |= values[15 + valuesStart] << 35;
        w11 = values[15 + valuesStart] >>> 29;
        w11 |= values[16 + valuesStart] << 16;
        w11 |= values[17 + valuesStart] << 61;
        w12 = values[17 + valuesStart] >>> 3;
        w12 |= values[18 + valuesStart] << 42;
        w13 = values[18 + valuesStart] >>> 22;
        w13 |= values[19 + valuesStart] << 23;
        w14 = values[19 + valuesStart] >>> 41;
        w14 |= values[20 + valuesStart] << 4;
        w14 |= values[21 + valuesStart] << 49;
        w15 = values[21 + valuesStart] >>> 15;
        w15 |= values[22 + valuesStart] << 30;
        w16 = values[22 + valuesStart] >>> 34;
        w16 |= values[23 + valuesStart] << 11;
        w16 |= values[24 + valuesStart] << 56;
        w17 = values[24 + valuesStart] >>> 8;
        w17 |= values[25 + valuesStart] << 37;
        w18 = values[25 + valuesStart] >>> 27;
        w18 |= values[26 + valuesStart] << 18;
        w18 |= values[27 + valuesStart] << 63;
        w19 = values[27 + valuesStart] >>> 1;
        w19 |= values[28 + valuesStart] << 44;
        w20 = values[28 + valuesStart] >>> 20;
        w20 |= values[29 + valuesStart] << 25;
        w21 = values[29 + valuesStart] >>> 39;
        w21 |= values[30 + valuesStart] << 6;
        w21 |= values[31 + valuesStart] << 51;
        w22 = values[31 + valuesStart] >>> 13;
        w22 |= values[32 + valuesStart] << 32;
        w23 = values[32 + valuesStart] >>> 32;
        w23 |= values[33 + valuesStart] << 13;
        w23 |= values[34 + valuesStart] << 58;
        w24 = values[34 + valuesStart] >>> 6;
        w24 |= values[35 + valuesStart] << 39;
        w25 = values[35 + valuesStart] >>> 25;
        w25 |= values[36 + valuesStart] << 20;
        w26 = values[36 + valuesStart] >>> 44;
        w26 |= values[37 + valuesStart] << 1;
        w26 |= values[38 + valuesStart] << 46;
        w27 = values[38 + valuesStart] >>> 18;
        w27 |= values[39 + valuesStart] << 27;
        w28 = values[39 + valuesStart] >>> 37;
        w28 |= values[40 + valuesStart] << 8;
        w28 |= values[41 + valuesStart] << 53;
        w29 = values[41 + valuesStart] >>> 11;
        w29 |= values[42 + valuesStart] << 34;
        w30 = values[42 + valuesStart] >>> 30;
        w30 |= values[43 + valuesStart] << 15;
        w30 |= values[44 + valuesStart] << 60;
        w31 = values[44 + valuesStart] >>> 4;
        w31 |= values[45 + valuesStart] << 41;
        w32 = values[45 + valuesStart] >>> 23;
        w32 |= values[46 + valuesStart] << 22;
        w33 = values[46 + valuesStart] >>> 42;
        w33 |= values[47 + valuesStart] << 3;
        w33 |= values[48 + valuesStart] << 48;
        w34 = values[48 + valuesStart] >>> 16;
        w34 |= values[49 + valuesStart] << 29;
        w35 = values[49 + valuesStart] >>> 35;
        w35 |= values[50 + valuesStart] << 10;
        w35 |= values[51 + valuesStart] << 55;
        w36 = values[51 + valuesStart] >>> 9;
        w36 |= values[52 + valuesStart] << 36;
        w37 = values[52 + valuesStart] >>> 28;
        w37 |= values[53 + valuesStart] << 17;
        w37 |= values[54 + valuesStart] << 62;
        w38 = values[54 + valuesStart] >>> 2;
        w38 |= values[55 + valuesStart] << 43;
        w39 = values[55 + valuesStart] >>> 21;
        w39 |= values[56 + valuesStart] << 24;
        w40 = values[56 + valuesStart] >>> 40;
        w40 |= values[57 + valuesStart] << 5;
        w40 |= values[58 + valuesStart] << 50;
        w41 = values[58 + valuesStart] >>> 14;
        w41 |= values[59 + valuesStart] << 31;
        w42 = values[59 + valuesStart] >>> 33;
        w42 |= values[60 + valuesStart] << 12;
        w42 |= values[61 + valuesStart] << 57;
        w43 = values[61 + valuesStart] >>> 7;
        w43 |= values[62 + valuesStart] << 38;
        w44 = values[62 + valuesStart] >>> 26;
        w44 |= values[63 + valuesStart] << 19;
        // Write to 360 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        return 360 + packedPtr;
    }

    /**
     * Packs 64 46-bit values into 368 bytes, touching 46 words.
     */
    private static long pack46(long[] values, int valuesStart, long packedPtr) {
        // Touching 46 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 46;
        w1 = values[1 + valuesStart] >>> 18;
        w1 |= values[2 + valuesStart] << 28;
        w2 = values[2 + valuesStart] >>> 36;
        w2 |= values[3 + valuesStart] << 10;
        w2 |= values[4 + valuesStart] << 56;
        w3 = values[4 + valuesStart] >>> 8;
        w3 |= values[5 + valuesStart] << 38;
        w4 = values[5 + valuesStart] >>> 26;
        w4 |= values[6 + valuesStart] << 20;
        w5 = values[6 + valuesStart] >>> 44;
        w5 |= values[7 + valuesStart] << 2;
        w5 |= values[8 + valuesStart] << 48;
        w6 = values[8 + valuesStart] >>> 16;
        w6 |= values[9 + valuesStart] << 30;
        w7 = values[9 + valuesStart] >>> 34;
        w7 |= values[10 + valuesStart] << 12;
        w7 |= values[11 + valuesStart] << 58;
        w8 = values[11 + valuesStart] >>> 6;
        w8 |= values[12 + valuesStart] << 40;
        w9 = values[12 + valuesStart] >>> 24;
        w9 |= values[13 + valuesStart] << 22;
        w10 = values[13 + valuesStart] >>> 42;
        w10 |= values[14 + valuesStart] << 4;
        w10 |= values[15 + valuesStart] << 50;
        w11 = values[15 + valuesStart] >>> 14;
        w11 |= values[16 + valuesStart] << 32;
        w12 = values[16 + valuesStart] >>> 32;
        w12 |= values[17 + valuesStart] << 14;
        w12 |= values[18 + valuesStart] << 60;
        w13 = values[18 + valuesStart] >>> 4;
        w13 |= values[19 + valuesStart] << 42;
        w14 = values[19 + valuesStart] >>> 22;
        w14 |= values[20 + valuesStart] << 24;
        w15 = values[20 + valuesStart] >>> 40;
        w15 |= values[21 + valuesStart] << 6;
        w15 |= values[22 + valuesStart] << 52;
        w16 = values[22 + valuesStart] >>> 12;
        w16 |= values[23 + valuesStart] << 34;
        w17 = values[23 + valuesStart] >>> 30;
        w17 |= values[24 + valuesStart] << 16;
        w17 |= values[25 + valuesStart] << 62;
        w18 = values[25 + valuesStart] >>> 2;
        w18 |= values[26 + valuesStart] << 44;
        w19 = values[26 + valuesStart] >>> 20;
        w19 |= values[27 + valuesStart] << 26;
        w20 = values[27 + valuesStart] >>> 38;
        w20 |= values[28 + valuesStart] << 8;
        w20 |= values[29 + valuesStart] << 54;
        w21 = values[29 + valuesStart] >>> 10;
        w21 |= values[30 + valuesStart] << 36;
        w22 = values[30 + valuesStart] >>> 28;
        w22 |= values[31 + valuesStart] << 18;
        w23 = values[32 + valuesStart];
        w23 |= values[33 + valuesStart] << 46;
        w24 = values[33 + valuesStart] >>> 18;
        w24 |= values[34 + valuesStart] << 28;
        w25 = values[34 + valuesStart] >>> 36;
        w25 |= values[35 + valuesStart] << 10;
        w25 |= values[36 + valuesStart] << 56;
        w26 = values[36 + valuesStart] >>> 8;
        w26 |= values[37 + valuesStart] << 38;
        w27 = values[37 + valuesStart] >>> 26;
        w27 |= values[38 + valuesStart] << 20;
        w28 = values[38 + valuesStart] >>> 44;
        w28 |= values[39 + valuesStart] << 2;
        w28 |= values[40 + valuesStart] << 48;
        w29 = values[40 + valuesStart] >>> 16;
        w29 |= values[41 + valuesStart] << 30;
        w30 = values[41 + valuesStart] >>> 34;
        w30 |= values[42 + valuesStart] << 12;
        w30 |= values[43 + valuesStart] << 58;
        w31 = values[43 + valuesStart] >>> 6;
        w31 |= values[44 + valuesStart] << 40;
        w32 = values[44 + valuesStart] >>> 24;
        w32 |= values[45 + valuesStart] << 22;
        w33 = values[45 + valuesStart] >>> 42;
        w33 |= values[46 + valuesStart] << 4;
        w33 |= values[47 + valuesStart] << 50;
        w34 = values[47 + valuesStart] >>> 14;
        w34 |= values[48 + valuesStart] << 32;
        w35 = values[48 + valuesStart] >>> 32;
        w35 |= values[49 + valuesStart] << 14;
        w35 |= values[50 + valuesStart] << 60;
        w36 = values[50 + valuesStart] >>> 4;
        w36 |= values[51 + valuesStart] << 42;
        w37 = values[51 + valuesStart] >>> 22;
        w37 |= values[52 + valuesStart] << 24;
        w38 = values[52 + valuesStart] >>> 40;
        w38 |= values[53 + valuesStart] << 6;
        w38 |= values[54 + valuesStart] << 52;
        w39 = values[54 + valuesStart] >>> 12;
        w39 |= values[55 + valuesStart] << 34;
        w40 = values[55 + valuesStart] >>> 30;
        w40 |= values[56 + valuesStart] << 16;
        w40 |= values[57 + valuesStart] << 62;
        w41 = values[57 + valuesStart] >>> 2;
        w41 |= values[58 + valuesStart] << 44;
        w42 = values[58 + valuesStart] >>> 20;
        w42 |= values[59 + valuesStart] << 26;
        w43 = values[59 + valuesStart] >>> 38;
        w43 |= values[60 + valuesStart] << 8;
        w43 |= values[61 + valuesStart] << 54;
        w44 = values[61 + valuesStart] >>> 10;
        w44 |= values[62 + valuesStart] << 36;
        w45 = values[62 + valuesStart] >>> 28;
        w45 |= values[63 + valuesStart] << 18;
        // Write to 368 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        return 368 + packedPtr;
    }

    /**
     * Packs 64 47-bit values into 376 bytes, touching 47 words.
     */
    private static long pack47(long[] values, int valuesStart, long packedPtr) {
        // Touching 47 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 47;
        w1 = values[1 + valuesStart] >>> 17;
        w1 |= values[2 + valuesStart] << 30;
        w2 = values[2 + valuesStart] >>> 34;
        w2 |= values[3 + valuesStart] << 13;
        w2 |= values[4 + valuesStart] << 60;
        w3 = values[4 + valuesStart] >>> 4;
        w3 |= values[5 + valuesStart] << 43;
        w4 = values[5 + valuesStart] >>> 21;
        w4 |= values[6 + valuesStart] << 26;
        w5 = values[6 + valuesStart] >>> 38;
        w5 |= values[7 + valuesStart] << 9;
        w5 |= values[8 + valuesStart] << 56;
        w6 = values[8 + valuesStart] >>> 8;
        w6 |= values[9 + valuesStart] << 39;
        w7 = values[9 + valuesStart] >>> 25;
        w7 |= values[10 + valuesStart] << 22;
        w8 = values[10 + valuesStart] >>> 42;
        w8 |= values[11 + valuesStart] << 5;
        w8 |= values[12 + valuesStart] << 52;
        w9 = values[12 + valuesStart] >>> 12;
        w9 |= values[13 + valuesStart] << 35;
        w10 = values[13 + valuesStart] >>> 29;
        w10 |= values[14 + valuesStart] << 18;
        w11 = values[14 + valuesStart] >>> 46;
        w11 |= values[15 + valuesStart] << 1;
        w11 |= values[16 + valuesStart] << 48;
        w12 = values[16 + valuesStart] >>> 16;
        w12 |= values[17 + valuesStart] << 31;
        w13 = values[17 + valuesStart] >>> 33;
        w13 |= values[18 + valuesStart] << 14;
        w13 |= values[19 + valuesStart] << 61;
        w14 = values[19 + valuesStart] >>> 3;
        w14 |= values[20 + valuesStart] << 44;
        w15 = values[20 + valuesStart] >>> 20;
        w15 |= values[21 + valuesStart] << 27;
        w16 = values[21 + valuesStart] >>> 37;
        w16 |= values[22 + valuesStart] << 10;
        w16 |= values[23 + valuesStart] << 57;
        w17 = values[23 + valuesStart] >>> 7;
        w17 |= values[24 + valuesStart] << 40;
        w18 = values[24 + valuesStart] >>> 24;
        w18 |= values[25 + valuesStart] << 23;
        w19 = values[25 + valuesStart] >>> 41;
        w19 |= values[26 + valuesStart] << 6;
        w19 |= values[27 + valuesStart] << 53;
        w20 = values[27 + valuesStart] >>> 11;
        w20 |= values[28 + valuesStart] << 36;
        w21 = values[28 + valuesStart] >>> 28;
        w21 |= values[29 + valuesStart] << 19;
        w22 = values[29 + valuesStart] >>> 45;
        w22 |= values[30 + valuesStart] << 2;
        w22 |= values[31 + valuesStart] << 49;
        w23 = values[31 + valuesStart] >>> 15;
        w23 |= values[32 + valuesStart] << 32;
        w24 = values[32 + valuesStart] >>> 32;
        w24 |= values[33 + valuesStart] << 15;
        w24 |= values[34 + valuesStart] << 62;
        w25 = values[34 + valuesStart] >>> 2;
        w25 |= values[35 + valuesStart] << 45;
        w26 = values[35 + valuesStart] >>> 19;
        w26 |= values[36 + valuesStart] << 28;
        w27 = values[36 + valuesStart] >>> 36;
        w27 |= values[37 + valuesStart] << 11;
        w27 |= values[38 + valuesStart] << 58;
        w28 = values[38 + valuesStart] >>> 6;
        w28 |= values[39 + valuesStart] << 41;
        w29 = values[39 + valuesStart] >>> 23;
        w29 |= values[40 + valuesStart] << 24;
        w30 = values[40 + valuesStart] >>> 40;
        w30 |= values[41 + valuesStart] << 7;
        w30 |= values[42 + valuesStart] << 54;
        w31 = values[42 + valuesStart] >>> 10;
        w31 |= values[43 + valuesStart] << 37;
        w32 = values[43 + valuesStart] >>> 27;
        w32 |= values[44 + valuesStart] << 20;
        w33 = values[44 + valuesStart] >>> 44;
        w33 |= values[45 + valuesStart] << 3;
        w33 |= values[46 + valuesStart] << 50;
        w34 = values[46 + valuesStart] >>> 14;
        w34 |= values[47 + valuesStart] << 33;
        w35 = values[47 + valuesStart] >>> 31;
        w35 |= values[48 + valuesStart] << 16;
        w35 |= values[49 + valuesStart] << 63;
        w36 = values[49 + valuesStart] >>> 1;
        w36 |= values[50 + valuesStart] << 46;
        w37 = values[50 + valuesStart] >>> 18;
        w37 |= values[51 + valuesStart] << 29;
        w38 = values[51 + valuesStart] >>> 35;
        w38 |= values[52 + valuesStart] << 12;
        w38 |= values[53 + valuesStart] << 59;
        w39 = values[53 + valuesStart] >>> 5;
        w39 |= values[54 + valuesStart] << 42;
        w40 = values[54 + valuesStart] >>> 22;
        w40 |= values[55 + valuesStart] << 25;
        w41 = values[55 + valuesStart] >>> 39;
        w41 |= values[56 + valuesStart] << 8;
        w41 |= values[57 + valuesStart] << 55;
        w42 = values[57 + valuesStart] >>> 9;
        w42 |= values[58 + valuesStart] << 38;
        w43 = values[58 + valuesStart] >>> 26;
        w43 |= values[59 + valuesStart] << 21;
        w44 = values[59 + valuesStart] >>> 43;
        w44 |= values[60 + valuesStart] << 4;
        w44 |= values[61 + valuesStart] << 51;
        w45 = values[61 + valuesStart] >>> 13;
        w45 |= values[62 + valuesStart] << 34;
        w46 = values[62 + valuesStart] >>> 30;
        w46 |= values[63 + valuesStart] << 17;
        // Write to 376 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        return 376 + packedPtr;
    }

    /**
     * Packs 64 48-bit values into 384 bytes, touching 48 words.
     */
    private static long pack48(long[] values, int valuesStart, long packedPtr) {
        // Touching 48 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 48;
        w1 = values[1 + valuesStart] >>> 16;
        w1 |= values[2 + valuesStart] << 32;
        w2 = values[2 + valuesStart] >>> 32;
        w2 |= values[3 + valuesStart] << 16;
        w3 = values[4 + valuesStart];
        w3 |= values[5 + valuesStart] << 48;
        w4 = values[5 + valuesStart] >>> 16;
        w4 |= values[6 + valuesStart] << 32;
        w5 = values[6 + valuesStart] >>> 32;
        w5 |= values[7 + valuesStart] << 16;
        w6 = values[8 + valuesStart];
        w6 |= values[9 + valuesStart] << 48;
        w7 = values[9 + valuesStart] >>> 16;
        w7 |= values[10 + valuesStart] << 32;
        w8 = values[10 + valuesStart] >>> 32;
        w8 |= values[11 + valuesStart] << 16;
        w9 = values[12 + valuesStart];
        w9 |= values[13 + valuesStart] << 48;
        w10 = values[13 + valuesStart] >>> 16;
        w10 |= values[14 + valuesStart] << 32;
        w11 = values[14 + valuesStart] >>> 32;
        w11 |= values[15 + valuesStart] << 16;
        w12 = values[16 + valuesStart];
        w12 |= values[17 + valuesStart] << 48;
        w13 = values[17 + valuesStart] >>> 16;
        w13 |= values[18 + valuesStart] << 32;
        w14 = values[18 + valuesStart] >>> 32;
        w14 |= values[19 + valuesStart] << 16;
        w15 = values[20 + valuesStart];
        w15 |= values[21 + valuesStart] << 48;
        w16 = values[21 + valuesStart] >>> 16;
        w16 |= values[22 + valuesStart] << 32;
        w17 = values[22 + valuesStart] >>> 32;
        w17 |= values[23 + valuesStart] << 16;
        w18 = values[24 + valuesStart];
        w18 |= values[25 + valuesStart] << 48;
        w19 = values[25 + valuesStart] >>> 16;
        w19 |= values[26 + valuesStart] << 32;
        w20 = values[26 + valuesStart] >>> 32;
        w20 |= values[27 + valuesStart] << 16;
        w21 = values[28 + valuesStart];
        w21 |= values[29 + valuesStart] << 48;
        w22 = values[29 + valuesStart] >>> 16;
        w22 |= values[30 + valuesStart] << 32;
        w23 = values[30 + valuesStart] >>> 32;
        w23 |= values[31 + valuesStart] << 16;
        w24 = values[32 + valuesStart];
        w24 |= values[33 + valuesStart] << 48;
        w25 = values[33 + valuesStart] >>> 16;
        w25 |= values[34 + valuesStart] << 32;
        w26 = values[34 + valuesStart] >>> 32;
        w26 |= values[35 + valuesStart] << 16;
        w27 = values[36 + valuesStart];
        w27 |= values[37 + valuesStart] << 48;
        w28 = values[37 + valuesStart] >>> 16;
        w28 |= values[38 + valuesStart] << 32;
        w29 = values[38 + valuesStart] >>> 32;
        w29 |= values[39 + valuesStart] << 16;
        w30 = values[40 + valuesStart];
        w30 |= values[41 + valuesStart] << 48;
        w31 = values[41 + valuesStart] >>> 16;
        w31 |= values[42 + valuesStart] << 32;
        w32 = values[42 + valuesStart] >>> 32;
        w32 |= values[43 + valuesStart] << 16;
        w33 = values[44 + valuesStart];
        w33 |= values[45 + valuesStart] << 48;
        w34 = values[45 + valuesStart] >>> 16;
        w34 |= values[46 + valuesStart] << 32;
        w35 = values[46 + valuesStart] >>> 32;
        w35 |= values[47 + valuesStart] << 16;
        w36 = values[48 + valuesStart];
        w36 |= values[49 + valuesStart] << 48;
        w37 = values[49 + valuesStart] >>> 16;
        w37 |= values[50 + valuesStart] << 32;
        w38 = values[50 + valuesStart] >>> 32;
        w38 |= values[51 + valuesStart] << 16;
        w39 = values[52 + valuesStart];
        w39 |= values[53 + valuesStart] << 48;
        w40 = values[53 + valuesStart] >>> 16;
        w40 |= values[54 + valuesStart] << 32;
        w41 = values[54 + valuesStart] >>> 32;
        w41 |= values[55 + valuesStart] << 16;
        w42 = values[56 + valuesStart];
        w42 |= values[57 + valuesStart] << 48;
        w43 = values[57 + valuesStart] >>> 16;
        w43 |= values[58 + valuesStart] << 32;
        w44 = values[58 + valuesStart] >>> 32;
        w44 |= values[59 + valuesStart] << 16;
        w45 = values[60 + valuesStart];
        w45 |= values[61 + valuesStart] << 48;
        w46 = values[61 + valuesStart] >>> 16;
        w46 |= values[62 + valuesStart] << 32;
        w47 = values[62 + valuesStart] >>> 32;
        w47 |= values[63 + valuesStart] << 16;
        // Write to 384 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        return 384 + packedPtr;
    }

    /**
     * Packs 64 49-bit values into 392 bytes, touching 49 words.
     */
    private static long pack49(long[] values, int valuesStart, long packedPtr) {
        // Touching 49 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        long w48;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 49;
        w1 = values[1 + valuesStart] >>> 15;
        w1 |= values[2 + valuesStart] << 34;
        w2 = values[2 + valuesStart] >>> 30;
        w2 |= values[3 + valuesStart] << 19;
        w3 = values[3 + valuesStart] >>> 45;
        w3 |= values[4 + valuesStart] << 4;
        w3 |= values[5 + valuesStart] << 53;
        w4 = values[5 + valuesStart] >>> 11;
        w4 |= values[6 + valuesStart] << 38;
        w5 = values[6 + valuesStart] >>> 26;
        w5 |= values[7 + valuesStart] << 23;
        w6 = values[7 + valuesStart] >>> 41;
        w6 |= values[8 + valuesStart] << 8;
        w6 |= values[9 + valuesStart] << 57;
        w7 = values[9 + valuesStart] >>> 7;
        w7 |= values[10 + valuesStart] << 42;
        w8 = values[10 + valuesStart] >>> 22;
        w8 |= values[11 + valuesStart] << 27;
        w9 = values[11 + valuesStart] >>> 37;
        w9 |= values[12 + valuesStart] << 12;
        w9 |= values[13 + valuesStart] << 61;
        w10 = values[13 + valuesStart] >>> 3;
        w10 |= values[14 + valuesStart] << 46;
        w11 = values[14 + valuesStart] >>> 18;
        w11 |= values[15 + valuesStart] << 31;
        w12 = values[15 + valuesStart] >>> 33;
        w12 |= values[16 + valuesStart] << 16;
        w13 = values[16 + valuesStart] >>> 48;
        w13 |= values[17 + valuesStart] << 1;
        w13 |= values[18 + valuesStart] << 50;
        w14 = values[18 + valuesStart] >>> 14;
        w14 |= values[19 + valuesStart] << 35;
        w15 = values[19 + valuesStart] >>> 29;
        w15 |= values[20 + valuesStart] << 20;
        w16 = values[20 + valuesStart] >>> 44;
        w16 |= values[21 + valuesStart] << 5;
        w16 |= values[22 + valuesStart] << 54;
        w17 = values[22 + valuesStart] >>> 10;
        w17 |= values[23 + valuesStart] << 39;
        w18 = values[23 + valuesStart] >>> 25;
        w18 |= values[24 + valuesStart] << 24;
        w19 = values[24 + valuesStart] >>> 40;
        w19 |= values[25 + valuesStart] << 9;
        w19 |= values[26 + valuesStart] << 58;
        w20 = values[26 + valuesStart] >>> 6;
        w20 |= values[27 + valuesStart] << 43;
        w21 = values[27 + valuesStart] >>> 21;
        w21 |= values[28 + valuesStart] << 28;
        w22 = values[28 + valuesStart] >>> 36;
        w22 |= values[29 + valuesStart] << 13;
        w22 |= values[30 + valuesStart] << 62;
        w23 = values[30 + valuesStart] >>> 2;
        w23 |= values[31 + valuesStart] << 47;
        w24 = values[31 + valuesStart] >>> 17;
        w24 |= values[32 + valuesStart] << 32;
        w25 = values[32 + valuesStart] >>> 32;
        w25 |= values[33 + valuesStart] << 17;
        w26 = values[33 + valuesStart] >>> 47;
        w26 |= values[34 + valuesStart] << 2;
        w26 |= values[35 + valuesStart] << 51;
        w27 = values[35 + valuesStart] >>> 13;
        w27 |= values[36 + valuesStart] << 36;
        w28 = values[36 + valuesStart] >>> 28;
        w28 |= values[37 + valuesStart] << 21;
        w29 = values[37 + valuesStart] >>> 43;
        w29 |= values[38 + valuesStart] << 6;
        w29 |= values[39 + valuesStart] << 55;
        w30 = values[39 + valuesStart] >>> 9;
        w30 |= values[40 + valuesStart] << 40;
        w31 = values[40 + valuesStart] >>> 24;
        w31 |= values[41 + valuesStart] << 25;
        w32 = values[41 + valuesStart] >>> 39;
        w32 |= values[42 + valuesStart] << 10;
        w32 |= values[43 + valuesStart] << 59;
        w33 = values[43 + valuesStart] >>> 5;
        w33 |= values[44 + valuesStart] << 44;
        w34 = values[44 + valuesStart] >>> 20;
        w34 |= values[45 + valuesStart] << 29;
        w35 = values[45 + valuesStart] >>> 35;
        w35 |= values[46 + valuesStart] << 14;
        w35 |= values[47 + valuesStart] << 63;
        w36 = values[47 + valuesStart] >>> 1;
        w36 |= values[48 + valuesStart] << 48;
        w37 = values[48 + valuesStart] >>> 16;
        w37 |= values[49 + valuesStart] << 33;
        w38 = values[49 + valuesStart] >>> 31;
        w38 |= values[50 + valuesStart] << 18;
        w39 = values[50 + valuesStart] >>> 46;
        w39 |= values[51 + valuesStart] << 3;
        w39 |= values[52 + valuesStart] << 52;
        w40 = values[52 + valuesStart] >>> 12;
        w40 |= values[53 + valuesStart] << 37;
        w41 = values[53 + valuesStart] >>> 27;
        w41 |= values[54 + valuesStart] << 22;
        w42 = values[54 + valuesStart] >>> 42;
        w42 |= values[55 + valuesStart] << 7;
        w42 |= values[56 + valuesStart] << 56;
        w43 = values[56 + valuesStart] >>> 8;
        w43 |= values[57 + valuesStart] << 41;
        w44 = values[57 + valuesStart] >>> 23;
        w44 |= values[58 + valuesStart] << 26;
        w45 = values[58 + valuesStart] >>> 38;
        w45 |= values[59 + valuesStart] << 11;
        w45 |= values[60 + valuesStart] << 60;
        w46 = values[60 + valuesStart] >>> 4;
        w46 |= values[61 + valuesStart] << 45;
        w47 = values[61 + valuesStart] >>> 19;
        w47 |= values[62 + valuesStart] << 30;
        w48 = values[62 + valuesStart] >>> 34;
        w48 |= values[63 + valuesStart] << 15;
        // Write to 392 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        UnsafeUtil.putLong(384 + packedPtr, w48);
        return 392 + packedPtr;
    }

    /**
     * Packs 64 50-bit values into 400 bytes, touching 50 words.
     */
    private static long pack50(long[] values, int valuesStart, long packedPtr) {
        // Touching 50 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        long w48;
        long w49;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 50;
        w1 = values[1 + valuesStart] >>> 14;
        w1 |= values[2 + valuesStart] << 36;
        w2 = values[2 + valuesStart] >>> 28;
        w2 |= values[3 + valuesStart] << 22;
        w3 = values[3 + valuesStart] >>> 42;
        w3 |= values[4 + valuesStart] << 8;
        w3 |= values[5 + valuesStart] << 58;
        w4 = values[5 + valuesStart] >>> 6;
        w4 |= values[6 + valuesStart] << 44;
        w5 = values[6 + valuesStart] >>> 20;
        w5 |= values[7 + valuesStart] << 30;
        w6 = values[7 + valuesStart] >>> 34;
        w6 |= values[8 + valuesStart] << 16;
        w7 = values[8 + valuesStart] >>> 48;
        w7 |= values[9 + valuesStart] << 2;
        w7 |= values[10 + valuesStart] << 52;
        w8 = values[10 + valuesStart] >>> 12;
        w8 |= values[11 + valuesStart] << 38;
        w9 = values[11 + valuesStart] >>> 26;
        w9 |= values[12 + valuesStart] << 24;
        w10 = values[12 + valuesStart] >>> 40;
        w10 |= values[13 + valuesStart] << 10;
        w10 |= values[14 + valuesStart] << 60;
        w11 = values[14 + valuesStart] >>> 4;
        w11 |= values[15 + valuesStart] << 46;
        w12 = values[15 + valuesStart] >>> 18;
        w12 |= values[16 + valuesStart] << 32;
        w13 = values[16 + valuesStart] >>> 32;
        w13 |= values[17 + valuesStart] << 18;
        w14 = values[17 + valuesStart] >>> 46;
        w14 |= values[18 + valuesStart] << 4;
        w14 |= values[19 + valuesStart] << 54;
        w15 = values[19 + valuesStart] >>> 10;
        w15 |= values[20 + valuesStart] << 40;
        w16 = values[20 + valuesStart] >>> 24;
        w16 |= values[21 + valuesStart] << 26;
        w17 = values[21 + valuesStart] >>> 38;
        w17 |= values[22 + valuesStart] << 12;
        w17 |= values[23 + valuesStart] << 62;
        w18 = values[23 + valuesStart] >>> 2;
        w18 |= values[24 + valuesStart] << 48;
        w19 = values[24 + valuesStart] >>> 16;
        w19 |= values[25 + valuesStart] << 34;
        w20 = values[25 + valuesStart] >>> 30;
        w20 |= values[26 + valuesStart] << 20;
        w21 = values[26 + valuesStart] >>> 44;
        w21 |= values[27 + valuesStart] << 6;
        w21 |= values[28 + valuesStart] << 56;
        w22 = values[28 + valuesStart] >>> 8;
        w22 |= values[29 + valuesStart] << 42;
        w23 = values[29 + valuesStart] >>> 22;
        w23 |= values[30 + valuesStart] << 28;
        w24 = values[30 + valuesStart] >>> 36;
        w24 |= values[31 + valuesStart] << 14;
        w25 = values[32 + valuesStart];
        w25 |= values[33 + valuesStart] << 50;
        w26 = values[33 + valuesStart] >>> 14;
        w26 |= values[34 + valuesStart] << 36;
        w27 = values[34 + valuesStart] >>> 28;
        w27 |= values[35 + valuesStart] << 22;
        w28 = values[35 + valuesStart] >>> 42;
        w28 |= values[36 + valuesStart] << 8;
        w28 |= values[37 + valuesStart] << 58;
        w29 = values[37 + valuesStart] >>> 6;
        w29 |= values[38 + valuesStart] << 44;
        w30 = values[38 + valuesStart] >>> 20;
        w30 |= values[39 + valuesStart] << 30;
        w31 = values[39 + valuesStart] >>> 34;
        w31 |= values[40 + valuesStart] << 16;
        w32 = values[40 + valuesStart] >>> 48;
        w32 |= values[41 + valuesStart] << 2;
        w32 |= values[42 + valuesStart] << 52;
        w33 = values[42 + valuesStart] >>> 12;
        w33 |= values[43 + valuesStart] << 38;
        w34 = values[43 + valuesStart] >>> 26;
        w34 |= values[44 + valuesStart] << 24;
        w35 = values[44 + valuesStart] >>> 40;
        w35 |= values[45 + valuesStart] << 10;
        w35 |= values[46 + valuesStart] << 60;
        w36 = values[46 + valuesStart] >>> 4;
        w36 |= values[47 + valuesStart] << 46;
        w37 = values[47 + valuesStart] >>> 18;
        w37 |= values[48 + valuesStart] << 32;
        w38 = values[48 + valuesStart] >>> 32;
        w38 |= values[49 + valuesStart] << 18;
        w39 = values[49 + valuesStart] >>> 46;
        w39 |= values[50 + valuesStart] << 4;
        w39 |= values[51 + valuesStart] << 54;
        w40 = values[51 + valuesStart] >>> 10;
        w40 |= values[52 + valuesStart] << 40;
        w41 = values[52 + valuesStart] >>> 24;
        w41 |= values[53 + valuesStart] << 26;
        w42 = values[53 + valuesStart] >>> 38;
        w42 |= values[54 + valuesStart] << 12;
        w42 |= values[55 + valuesStart] << 62;
        w43 = values[55 + valuesStart] >>> 2;
        w43 |= values[56 + valuesStart] << 48;
        w44 = values[56 + valuesStart] >>> 16;
        w44 |= values[57 + valuesStart] << 34;
        w45 = values[57 + valuesStart] >>> 30;
        w45 |= values[58 + valuesStart] << 20;
        w46 = values[58 + valuesStart] >>> 44;
        w46 |= values[59 + valuesStart] << 6;
        w46 |= values[60 + valuesStart] << 56;
        w47 = values[60 + valuesStart] >>> 8;
        w47 |= values[61 + valuesStart] << 42;
        w48 = values[61 + valuesStart] >>> 22;
        w48 |= values[62 + valuesStart] << 28;
        w49 = values[62 + valuesStart] >>> 36;
        w49 |= values[63 + valuesStart] << 14;
        // Write to 400 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        UnsafeUtil.putLong(384 + packedPtr, w48);
        UnsafeUtil.putLong(392 + packedPtr, w49);
        return 400 + packedPtr;
    }

    /**
     * Packs 64 51-bit values into 408 bytes, touching 51 words.
     */
    private static long pack51(long[] values, int valuesStart, long packedPtr) {
        // Touching 51 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        long w48;
        long w49;
        long w50;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 51;
        w1 = values[1 + valuesStart] >>> 13;
        w1 |= values[2 + valuesStart] << 38;
        w2 = values[2 + valuesStart] >>> 26;
        w2 |= values[3 + valuesStart] << 25;
        w3 = values[3 + valuesStart] >>> 39;
        w3 |= values[4 + valuesStart] << 12;
        w3 |= values[5 + valuesStart] << 63;
        w4 = values[5 + valuesStart] >>> 1;
        w4 |= values[6 + valuesStart] << 50;
        w5 = values[6 + valuesStart] >>> 14;
        w5 |= values[7 + valuesStart] << 37;
        w6 = values[7 + valuesStart] >>> 27;
        w6 |= values[8 + valuesStart] << 24;
        w7 = values[8 + valuesStart] >>> 40;
        w7 |= values[9 + valuesStart] << 11;
        w7 |= values[10 + valuesStart] << 62;
        w8 = values[10 + valuesStart] >>> 2;
        w8 |= values[11 + valuesStart] << 49;
        w9 = values[11 + valuesStart] >>> 15;
        w9 |= values[12 + valuesStart] << 36;
        w10 = values[12 + valuesStart] >>> 28;
        w10 |= values[13 + valuesStart] << 23;
        w11 = values[13 + valuesStart] >>> 41;
        w11 |= values[14 + valuesStart] << 10;
        w11 |= values[15 + valuesStart] << 61;
        w12 = values[15 + valuesStart] >>> 3;
        w12 |= values[16 + valuesStart] << 48;
        w13 = values[16 + valuesStart] >>> 16;
        w13 |= values[17 + valuesStart] << 35;
        w14 = values[17 + valuesStart] >>> 29;
        w14 |= values[18 + valuesStart] << 22;
        w15 = values[18 + valuesStart] >>> 42;
        w15 |= values[19 + valuesStart] << 9;
        w15 |= values[20 + valuesStart] << 60;
        w16 = values[20 + valuesStart] >>> 4;
        w16 |= values[21 + valuesStart] << 47;
        w17 = values[21 + valuesStart] >>> 17;
        w17 |= values[22 + valuesStart] << 34;
        w18 = values[22 + valuesStart] >>> 30;
        w18 |= values[23 + valuesStart] << 21;
        w19 = values[23 + valuesStart] >>> 43;
        w19 |= values[24 + valuesStart] << 8;
        w19 |= values[25 + valuesStart] << 59;
        w20 = values[25 + valuesStart] >>> 5;
        w20 |= values[26 + valuesStart] << 46;
        w21 = values[26 + valuesStart] >>> 18;
        w21 |= values[27 + valuesStart] << 33;
        w22 = values[27 + valuesStart] >>> 31;
        w22 |= values[28 + valuesStart] << 20;
        w23 = values[28 + valuesStart] >>> 44;
        w23 |= values[29 + valuesStart] << 7;
        w23 |= values[30 + valuesStart] << 58;
        w24 = values[30 + valuesStart] >>> 6;
        w24 |= values[31 + valuesStart] << 45;
        w25 = values[31 + valuesStart] >>> 19;
        w25 |= values[32 + valuesStart] << 32;
        w26 = values[32 + valuesStart] >>> 32;
        w26 |= values[33 + valuesStart] << 19;
        w27 = values[33 + valuesStart] >>> 45;
        w27 |= values[34 + valuesStart] << 6;
        w27 |= values[35 + valuesStart] << 57;
        w28 = values[35 + valuesStart] >>> 7;
        w28 |= values[36 + valuesStart] << 44;
        w29 = values[36 + valuesStart] >>> 20;
        w29 |= values[37 + valuesStart] << 31;
        w30 = values[37 + valuesStart] >>> 33;
        w30 |= values[38 + valuesStart] << 18;
        w31 = values[38 + valuesStart] >>> 46;
        w31 |= values[39 + valuesStart] << 5;
        w31 |= values[40 + valuesStart] << 56;
        w32 = values[40 + valuesStart] >>> 8;
        w32 |= values[41 + valuesStart] << 43;
        w33 = values[41 + valuesStart] >>> 21;
        w33 |= values[42 + valuesStart] << 30;
        w34 = values[42 + valuesStart] >>> 34;
        w34 |= values[43 + valuesStart] << 17;
        w35 = values[43 + valuesStart] >>> 47;
        w35 |= values[44 + valuesStart] << 4;
        w35 |= values[45 + valuesStart] << 55;
        w36 = values[45 + valuesStart] >>> 9;
        w36 |= values[46 + valuesStart] << 42;
        w37 = values[46 + valuesStart] >>> 22;
        w37 |= values[47 + valuesStart] << 29;
        w38 = values[47 + valuesStart] >>> 35;
        w38 |= values[48 + valuesStart] << 16;
        w39 = values[48 + valuesStart] >>> 48;
        w39 |= values[49 + valuesStart] << 3;
        w39 |= values[50 + valuesStart] << 54;
        w40 = values[50 + valuesStart] >>> 10;
        w40 |= values[51 + valuesStart] << 41;
        w41 = values[51 + valuesStart] >>> 23;
        w41 |= values[52 + valuesStart] << 28;
        w42 = values[52 + valuesStart] >>> 36;
        w42 |= values[53 + valuesStart] << 15;
        w43 = values[53 + valuesStart] >>> 49;
        w43 |= values[54 + valuesStart] << 2;
        w43 |= values[55 + valuesStart] << 53;
        w44 = values[55 + valuesStart] >>> 11;
        w44 |= values[56 + valuesStart] << 40;
        w45 = values[56 + valuesStart] >>> 24;
        w45 |= values[57 + valuesStart] << 27;
        w46 = values[57 + valuesStart] >>> 37;
        w46 |= values[58 + valuesStart] << 14;
        w47 = values[58 + valuesStart] >>> 50;
        w47 |= values[59 + valuesStart] << 1;
        w47 |= values[60 + valuesStart] << 52;
        w48 = values[60 + valuesStart] >>> 12;
        w48 |= values[61 + valuesStart] << 39;
        w49 = values[61 + valuesStart] >>> 25;
        w49 |= values[62 + valuesStart] << 26;
        w50 = values[62 + valuesStart] >>> 38;
        w50 |= values[63 + valuesStart] << 13;
        // Write to 408 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        UnsafeUtil.putLong(384 + packedPtr, w48);
        UnsafeUtil.putLong(392 + packedPtr, w49);
        UnsafeUtil.putLong(400 + packedPtr, w50);
        return 408 + packedPtr;
    }

    /**
     * Packs 64 52-bit values into 416 bytes, touching 52 words.
     */
    private static long pack52(long[] values, int valuesStart, long packedPtr) {
        // Touching 52 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        long w48;
        long w49;
        long w50;
        long w51;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 52;
        w1 = values[1 + valuesStart] >>> 12;
        w1 |= values[2 + valuesStart] << 40;
        w2 = values[2 + valuesStart] >>> 24;
        w2 |= values[3 + valuesStart] << 28;
        w3 = values[3 + valuesStart] >>> 36;
        w3 |= values[4 + valuesStart] << 16;
        w4 = values[4 + valuesStart] >>> 48;
        w4 |= values[5 + valuesStart] << 4;
        w4 |= values[6 + valuesStart] << 56;
        w5 = values[6 + valuesStart] >>> 8;
        w5 |= values[7 + valuesStart] << 44;
        w6 = values[7 + valuesStart] >>> 20;
        w6 |= values[8 + valuesStart] << 32;
        w7 = values[8 + valuesStart] >>> 32;
        w7 |= values[9 + valuesStart] << 20;
        w8 = values[9 + valuesStart] >>> 44;
        w8 |= values[10 + valuesStart] << 8;
        w8 |= values[11 + valuesStart] << 60;
        w9 = values[11 + valuesStart] >>> 4;
        w9 |= values[12 + valuesStart] << 48;
        w10 = values[12 + valuesStart] >>> 16;
        w10 |= values[13 + valuesStart] << 36;
        w11 = values[13 + valuesStart] >>> 28;
        w11 |= values[14 + valuesStart] << 24;
        w12 = values[14 + valuesStart] >>> 40;
        w12 |= values[15 + valuesStart] << 12;
        w13 = values[16 + valuesStart];
        w13 |= values[17 + valuesStart] << 52;
        w14 = values[17 + valuesStart] >>> 12;
        w14 |= values[18 + valuesStart] << 40;
        w15 = values[18 + valuesStart] >>> 24;
        w15 |= values[19 + valuesStart] << 28;
        w16 = values[19 + valuesStart] >>> 36;
        w16 |= values[20 + valuesStart] << 16;
        w17 = values[20 + valuesStart] >>> 48;
        w17 |= values[21 + valuesStart] << 4;
        w17 |= values[22 + valuesStart] << 56;
        w18 = values[22 + valuesStart] >>> 8;
        w18 |= values[23 + valuesStart] << 44;
        w19 = values[23 + valuesStart] >>> 20;
        w19 |= values[24 + valuesStart] << 32;
        w20 = values[24 + valuesStart] >>> 32;
        w20 |= values[25 + valuesStart] << 20;
        w21 = values[25 + valuesStart] >>> 44;
        w21 |= values[26 + valuesStart] << 8;
        w21 |= values[27 + valuesStart] << 60;
        w22 = values[27 + valuesStart] >>> 4;
        w22 |= values[28 + valuesStart] << 48;
        w23 = values[28 + valuesStart] >>> 16;
        w23 |= values[29 + valuesStart] << 36;
        w24 = values[29 + valuesStart] >>> 28;
        w24 |= values[30 + valuesStart] << 24;
        w25 = values[30 + valuesStart] >>> 40;
        w25 |= values[31 + valuesStart] << 12;
        w26 = values[32 + valuesStart];
        w26 |= values[33 + valuesStart] << 52;
        w27 = values[33 + valuesStart] >>> 12;
        w27 |= values[34 + valuesStart] << 40;
        w28 = values[34 + valuesStart] >>> 24;
        w28 |= values[35 + valuesStart] << 28;
        w29 = values[35 + valuesStart] >>> 36;
        w29 |= values[36 + valuesStart] << 16;
        w30 = values[36 + valuesStart] >>> 48;
        w30 |= values[37 + valuesStart] << 4;
        w30 |= values[38 + valuesStart] << 56;
        w31 = values[38 + valuesStart] >>> 8;
        w31 |= values[39 + valuesStart] << 44;
        w32 = values[39 + valuesStart] >>> 20;
        w32 |= values[40 + valuesStart] << 32;
        w33 = values[40 + valuesStart] >>> 32;
        w33 |= values[41 + valuesStart] << 20;
        w34 = values[41 + valuesStart] >>> 44;
        w34 |= values[42 + valuesStart] << 8;
        w34 |= values[43 + valuesStart] << 60;
        w35 = values[43 + valuesStart] >>> 4;
        w35 |= values[44 + valuesStart] << 48;
        w36 = values[44 + valuesStart] >>> 16;
        w36 |= values[45 + valuesStart] << 36;
        w37 = values[45 + valuesStart] >>> 28;
        w37 |= values[46 + valuesStart] << 24;
        w38 = values[46 + valuesStart] >>> 40;
        w38 |= values[47 + valuesStart] << 12;
        w39 = values[48 + valuesStart];
        w39 |= values[49 + valuesStart] << 52;
        w40 = values[49 + valuesStart] >>> 12;
        w40 |= values[50 + valuesStart] << 40;
        w41 = values[50 + valuesStart] >>> 24;
        w41 |= values[51 + valuesStart] << 28;
        w42 = values[51 + valuesStart] >>> 36;
        w42 |= values[52 + valuesStart] << 16;
        w43 = values[52 + valuesStart] >>> 48;
        w43 |= values[53 + valuesStart] << 4;
        w43 |= values[54 + valuesStart] << 56;
        w44 = values[54 + valuesStart] >>> 8;
        w44 |= values[55 + valuesStart] << 44;
        w45 = values[55 + valuesStart] >>> 20;
        w45 |= values[56 + valuesStart] << 32;
        w46 = values[56 + valuesStart] >>> 32;
        w46 |= values[57 + valuesStart] << 20;
        w47 = values[57 + valuesStart] >>> 44;
        w47 |= values[58 + valuesStart] << 8;
        w47 |= values[59 + valuesStart] << 60;
        w48 = values[59 + valuesStart] >>> 4;
        w48 |= values[60 + valuesStart] << 48;
        w49 = values[60 + valuesStart] >>> 16;
        w49 |= values[61 + valuesStart] << 36;
        w50 = values[61 + valuesStart] >>> 28;
        w50 |= values[62 + valuesStart] << 24;
        w51 = values[62 + valuesStart] >>> 40;
        w51 |= values[63 + valuesStart] << 12;
        // Write to 416 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        UnsafeUtil.putLong(384 + packedPtr, w48);
        UnsafeUtil.putLong(392 + packedPtr, w49);
        UnsafeUtil.putLong(400 + packedPtr, w50);
        UnsafeUtil.putLong(408 + packedPtr, w51);
        return 416 + packedPtr;
    }

    /**
     * Packs 64 53-bit values into 424 bytes, touching 53 words.
     */
    private static long pack53(long[] values, int valuesStart, long packedPtr) {
        // Touching 53 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        long w48;
        long w49;
        long w50;
        long w51;
        long w52;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 53;
        w1 = values[1 + valuesStart] >>> 11;
        w1 |= values[2 + valuesStart] << 42;
        w2 = values[2 + valuesStart] >>> 22;
        w2 |= values[3 + valuesStart] << 31;
        w3 = values[3 + valuesStart] >>> 33;
        w3 |= values[4 + valuesStart] << 20;
        w4 = values[4 + valuesStart] >>> 44;
        w4 |= values[5 + valuesStart] << 9;
        w4 |= values[6 + valuesStart] << 62;
        w5 = values[6 + valuesStart] >>> 2;
        w5 |= values[7 + valuesStart] << 51;
        w6 = values[7 + valuesStart] >>> 13;
        w6 |= values[8 + valuesStart] << 40;
        w7 = values[8 + valuesStart] >>> 24;
        w7 |= values[9 + valuesStart] << 29;
        w8 = values[9 + valuesStart] >>> 35;
        w8 |= values[10 + valuesStart] << 18;
        w9 = values[10 + valuesStart] >>> 46;
        w9 |= values[11 + valuesStart] << 7;
        w9 |= values[12 + valuesStart] << 60;
        w10 = values[12 + valuesStart] >>> 4;
        w10 |= values[13 + valuesStart] << 49;
        w11 = values[13 + valuesStart] >>> 15;
        w11 |= values[14 + valuesStart] << 38;
        w12 = values[14 + valuesStart] >>> 26;
        w12 |= values[15 + valuesStart] << 27;
        w13 = values[15 + valuesStart] >>> 37;
        w13 |= values[16 + valuesStart] << 16;
        w14 = values[16 + valuesStart] >>> 48;
        w14 |= values[17 + valuesStart] << 5;
        w14 |= values[18 + valuesStart] << 58;
        w15 = values[18 + valuesStart] >>> 6;
        w15 |= values[19 + valuesStart] << 47;
        w16 = values[19 + valuesStart] >>> 17;
        w16 |= values[20 + valuesStart] << 36;
        w17 = values[20 + valuesStart] >>> 28;
        w17 |= values[21 + valuesStart] << 25;
        w18 = values[21 + valuesStart] >>> 39;
        w18 |= values[22 + valuesStart] << 14;
        w19 = values[22 + valuesStart] >>> 50;
        w19 |= values[23 + valuesStart] << 3;
        w19 |= values[24 + valuesStart] << 56;
        w20 = values[24 + valuesStart] >>> 8;
        w20 |= values[25 + valuesStart] << 45;
        w21 = values[25 + valuesStart] >>> 19;
        w21 |= values[26 + valuesStart] << 34;
        w22 = values[26 + valuesStart] >>> 30;
        w22 |= values[27 + valuesStart] << 23;
        w23 = values[27 + valuesStart] >>> 41;
        w23 |= values[28 + valuesStart] << 12;
        w24 = values[28 + valuesStart] >>> 52;
        w24 |= values[29 + valuesStart] << 1;
        w24 |= values[30 + valuesStart] << 54;
        w25 = values[30 + valuesStart] >>> 10;
        w25 |= values[31 + valuesStart] << 43;
        w26 = values[31 + valuesStart] >>> 21;
        w26 |= values[32 + valuesStart] << 32;
        w27 = values[32 + valuesStart] >>> 32;
        w27 |= values[33 + valuesStart] << 21;
        w28 = values[33 + valuesStart] >>> 43;
        w28 |= values[34 + valuesStart] << 10;
        w28 |= values[35 + valuesStart] << 63;
        w29 = values[35 + valuesStart] >>> 1;
        w29 |= values[36 + valuesStart] << 52;
        w30 = values[36 + valuesStart] >>> 12;
        w30 |= values[37 + valuesStart] << 41;
        w31 = values[37 + valuesStart] >>> 23;
        w31 |= values[38 + valuesStart] << 30;
        w32 = values[38 + valuesStart] >>> 34;
        w32 |= values[39 + valuesStart] << 19;
        w33 = values[39 + valuesStart] >>> 45;
        w33 |= values[40 + valuesStart] << 8;
        w33 |= values[41 + valuesStart] << 61;
        w34 = values[41 + valuesStart] >>> 3;
        w34 |= values[42 + valuesStart] << 50;
        w35 = values[42 + valuesStart] >>> 14;
        w35 |= values[43 + valuesStart] << 39;
        w36 = values[43 + valuesStart] >>> 25;
        w36 |= values[44 + valuesStart] << 28;
        w37 = values[44 + valuesStart] >>> 36;
        w37 |= values[45 + valuesStart] << 17;
        w38 = values[45 + valuesStart] >>> 47;
        w38 |= values[46 + valuesStart] << 6;
        w38 |= values[47 + valuesStart] << 59;
        w39 = values[47 + valuesStart] >>> 5;
        w39 |= values[48 + valuesStart] << 48;
        w40 = values[48 + valuesStart] >>> 16;
        w40 |= values[49 + valuesStart] << 37;
        w41 = values[49 + valuesStart] >>> 27;
        w41 |= values[50 + valuesStart] << 26;
        w42 = values[50 + valuesStart] >>> 38;
        w42 |= values[51 + valuesStart] << 15;
        w43 = values[51 + valuesStart] >>> 49;
        w43 |= values[52 + valuesStart] << 4;
        w43 |= values[53 + valuesStart] << 57;
        w44 = values[53 + valuesStart] >>> 7;
        w44 |= values[54 + valuesStart] << 46;
        w45 = values[54 + valuesStart] >>> 18;
        w45 |= values[55 + valuesStart] << 35;
        w46 = values[55 + valuesStart] >>> 29;
        w46 |= values[56 + valuesStart] << 24;
        w47 = values[56 + valuesStart] >>> 40;
        w47 |= values[57 + valuesStart] << 13;
        w48 = values[57 + valuesStart] >>> 51;
        w48 |= values[58 + valuesStart] << 2;
        w48 |= values[59 + valuesStart] << 55;
        w49 = values[59 + valuesStart] >>> 9;
        w49 |= values[60 + valuesStart] << 44;
        w50 = values[60 + valuesStart] >>> 20;
        w50 |= values[61 + valuesStart] << 33;
        w51 = values[61 + valuesStart] >>> 31;
        w51 |= values[62 + valuesStart] << 22;
        w52 = values[62 + valuesStart] >>> 42;
        w52 |= values[63 + valuesStart] << 11;
        // Write to 424 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        UnsafeUtil.putLong(384 + packedPtr, w48);
        UnsafeUtil.putLong(392 + packedPtr, w49);
        UnsafeUtil.putLong(400 + packedPtr, w50);
        UnsafeUtil.putLong(408 + packedPtr, w51);
        UnsafeUtil.putLong(416 + packedPtr, w52);
        return 424 + packedPtr;
    }

    /**
     * Packs 64 54-bit values into 432 bytes, touching 54 words.
     */
    private static long pack54(long[] values, int valuesStart, long packedPtr) {
        // Touching 54 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        long w48;
        long w49;
        long w50;
        long w51;
        long w52;
        long w53;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 54;
        w1 = values[1 + valuesStart] >>> 10;
        w1 |= values[2 + valuesStart] << 44;
        w2 = values[2 + valuesStart] >>> 20;
        w2 |= values[3 + valuesStart] << 34;
        w3 = values[3 + valuesStart] >>> 30;
        w3 |= values[4 + valuesStart] << 24;
        w4 = values[4 + valuesStart] >>> 40;
        w4 |= values[5 + valuesStart] << 14;
        w5 = values[5 + valuesStart] >>> 50;
        w5 |= values[6 + valuesStart] << 4;
        w5 |= values[7 + valuesStart] << 58;
        w6 = values[7 + valuesStart] >>> 6;
        w6 |= values[8 + valuesStart] << 48;
        w7 = values[8 + valuesStart] >>> 16;
        w7 |= values[9 + valuesStart] << 38;
        w8 = values[9 + valuesStart] >>> 26;
        w8 |= values[10 + valuesStart] << 28;
        w9 = values[10 + valuesStart] >>> 36;
        w9 |= values[11 + valuesStart] << 18;
        w10 = values[11 + valuesStart] >>> 46;
        w10 |= values[12 + valuesStart] << 8;
        w10 |= values[13 + valuesStart] << 62;
        w11 = values[13 + valuesStart] >>> 2;
        w11 |= values[14 + valuesStart] << 52;
        w12 = values[14 + valuesStart] >>> 12;
        w12 |= values[15 + valuesStart] << 42;
        w13 = values[15 + valuesStart] >>> 22;
        w13 |= values[16 + valuesStart] << 32;
        w14 = values[16 + valuesStart] >>> 32;
        w14 |= values[17 + valuesStart] << 22;
        w15 = values[17 + valuesStart] >>> 42;
        w15 |= values[18 + valuesStart] << 12;
        w16 = values[18 + valuesStart] >>> 52;
        w16 |= values[19 + valuesStart] << 2;
        w16 |= values[20 + valuesStart] << 56;
        w17 = values[20 + valuesStart] >>> 8;
        w17 |= values[21 + valuesStart] << 46;
        w18 = values[21 + valuesStart] >>> 18;
        w18 |= values[22 + valuesStart] << 36;
        w19 = values[22 + valuesStart] >>> 28;
        w19 |= values[23 + valuesStart] << 26;
        w20 = values[23 + valuesStart] >>> 38;
        w20 |= values[24 + valuesStart] << 16;
        w21 = values[24 + valuesStart] >>> 48;
        w21 |= values[25 + valuesStart] << 6;
        w21 |= values[26 + valuesStart] << 60;
        w22 = values[26 + valuesStart] >>> 4;
        w22 |= values[27 + valuesStart] << 50;
        w23 = values[27 + valuesStart] >>> 14;
        w23 |= values[28 + valuesStart] << 40;
        w24 = values[28 + valuesStart] >>> 24;
        w24 |= values[29 + valuesStart] << 30;
        w25 = values[29 + valuesStart] >>> 34;
        w25 |= values[30 + valuesStart] << 20;
        w26 = values[30 + valuesStart] >>> 44;
        w26 |= values[31 + valuesStart] << 10;
        w27 = values[32 + valuesStart];
        w27 |= values[33 + valuesStart] << 54;
        w28 = values[33 + valuesStart] >>> 10;
        w28 |= values[34 + valuesStart] << 44;
        w29 = values[34 + valuesStart] >>> 20;
        w29 |= values[35 + valuesStart] << 34;
        w30 = values[35 + valuesStart] >>> 30;
        w30 |= values[36 + valuesStart] << 24;
        w31 = values[36 + valuesStart] >>> 40;
        w31 |= values[37 + valuesStart] << 14;
        w32 = values[37 + valuesStart] >>> 50;
        w32 |= values[38 + valuesStart] << 4;
        w32 |= values[39 + valuesStart] << 58;
        w33 = values[39 + valuesStart] >>> 6;
        w33 |= values[40 + valuesStart] << 48;
        w34 = values[40 + valuesStart] >>> 16;
        w34 |= values[41 + valuesStart] << 38;
        w35 = values[41 + valuesStart] >>> 26;
        w35 |= values[42 + valuesStart] << 28;
        w36 = values[42 + valuesStart] >>> 36;
        w36 |= values[43 + valuesStart] << 18;
        w37 = values[43 + valuesStart] >>> 46;
        w37 |= values[44 + valuesStart] << 8;
        w37 |= values[45 + valuesStart] << 62;
        w38 = values[45 + valuesStart] >>> 2;
        w38 |= values[46 + valuesStart] << 52;
        w39 = values[46 + valuesStart] >>> 12;
        w39 |= values[47 + valuesStart] << 42;
        w40 = values[47 + valuesStart] >>> 22;
        w40 |= values[48 + valuesStart] << 32;
        w41 = values[48 + valuesStart] >>> 32;
        w41 |= values[49 + valuesStart] << 22;
        w42 = values[49 + valuesStart] >>> 42;
        w42 |= values[50 + valuesStart] << 12;
        w43 = values[50 + valuesStart] >>> 52;
        w43 |= values[51 + valuesStart] << 2;
        w43 |= values[52 + valuesStart] << 56;
        w44 = values[52 + valuesStart] >>> 8;
        w44 |= values[53 + valuesStart] << 46;
        w45 = values[53 + valuesStart] >>> 18;
        w45 |= values[54 + valuesStart] << 36;
        w46 = values[54 + valuesStart] >>> 28;
        w46 |= values[55 + valuesStart] << 26;
        w47 = values[55 + valuesStart] >>> 38;
        w47 |= values[56 + valuesStart] << 16;
        w48 = values[56 + valuesStart] >>> 48;
        w48 |= values[57 + valuesStart] << 6;
        w48 |= values[58 + valuesStart] << 60;
        w49 = values[58 + valuesStart] >>> 4;
        w49 |= values[59 + valuesStart] << 50;
        w50 = values[59 + valuesStart] >>> 14;
        w50 |= values[60 + valuesStart] << 40;
        w51 = values[60 + valuesStart] >>> 24;
        w51 |= values[61 + valuesStart] << 30;
        w52 = values[61 + valuesStart] >>> 34;
        w52 |= values[62 + valuesStart] << 20;
        w53 = values[62 + valuesStart] >>> 44;
        w53 |= values[63 + valuesStart] << 10;
        // Write to 432 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        UnsafeUtil.putLong(384 + packedPtr, w48);
        UnsafeUtil.putLong(392 + packedPtr, w49);
        UnsafeUtil.putLong(400 + packedPtr, w50);
        UnsafeUtil.putLong(408 + packedPtr, w51);
        UnsafeUtil.putLong(416 + packedPtr, w52);
        UnsafeUtil.putLong(424 + packedPtr, w53);
        return 432 + packedPtr;
    }

    /**
     * Packs 64 55-bit values into 440 bytes, touching 55 words.
     */
    private static long pack55(long[] values, int valuesStart, long packedPtr) {
        // Touching 55 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        long w48;
        long w49;
        long w50;
        long w51;
        long w52;
        long w53;
        long w54;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 55;
        w1 = values[1 + valuesStart] >>> 9;
        w1 |= values[2 + valuesStart] << 46;
        w2 = values[2 + valuesStart] >>> 18;
        w2 |= values[3 + valuesStart] << 37;
        w3 = values[3 + valuesStart] >>> 27;
        w3 |= values[4 + valuesStart] << 28;
        w4 = values[4 + valuesStart] >>> 36;
        w4 |= values[5 + valuesStart] << 19;
        w5 = values[5 + valuesStart] >>> 45;
        w5 |= values[6 + valuesStart] << 10;
        w6 = values[6 + valuesStart] >>> 54;
        w6 |= values[7 + valuesStart] << 1;
        w6 |= values[8 + valuesStart] << 56;
        w7 = values[8 + valuesStart] >>> 8;
        w7 |= values[9 + valuesStart] << 47;
        w8 = values[9 + valuesStart] >>> 17;
        w8 |= values[10 + valuesStart] << 38;
        w9 = values[10 + valuesStart] >>> 26;
        w9 |= values[11 + valuesStart] << 29;
        w10 = values[11 + valuesStart] >>> 35;
        w10 |= values[12 + valuesStart] << 20;
        w11 = values[12 + valuesStart] >>> 44;
        w11 |= values[13 + valuesStart] << 11;
        w12 = values[13 + valuesStart] >>> 53;
        w12 |= values[14 + valuesStart] << 2;
        w12 |= values[15 + valuesStart] << 57;
        w13 = values[15 + valuesStart] >>> 7;
        w13 |= values[16 + valuesStart] << 48;
        w14 = values[16 + valuesStart] >>> 16;
        w14 |= values[17 + valuesStart] << 39;
        w15 = values[17 + valuesStart] >>> 25;
        w15 |= values[18 + valuesStart] << 30;
        w16 = values[18 + valuesStart] >>> 34;
        w16 |= values[19 + valuesStart] << 21;
        w17 = values[19 + valuesStart] >>> 43;
        w17 |= values[20 + valuesStart] << 12;
        w18 = values[20 + valuesStart] >>> 52;
        w18 |= values[21 + valuesStart] << 3;
        w18 |= values[22 + valuesStart] << 58;
        w19 = values[22 + valuesStart] >>> 6;
        w19 |= values[23 + valuesStart] << 49;
        w20 = values[23 + valuesStart] >>> 15;
        w20 |= values[24 + valuesStart] << 40;
        w21 = values[24 + valuesStart] >>> 24;
        w21 |= values[25 + valuesStart] << 31;
        w22 = values[25 + valuesStart] >>> 33;
        w22 |= values[26 + valuesStart] << 22;
        w23 = values[26 + valuesStart] >>> 42;
        w23 |= values[27 + valuesStart] << 13;
        w24 = values[27 + valuesStart] >>> 51;
        w24 |= values[28 + valuesStart] << 4;
        w24 |= values[29 + valuesStart] << 59;
        w25 = values[29 + valuesStart] >>> 5;
        w25 |= values[30 + valuesStart] << 50;
        w26 = values[30 + valuesStart] >>> 14;
        w26 |= values[31 + valuesStart] << 41;
        w27 = values[31 + valuesStart] >>> 23;
        w27 |= values[32 + valuesStart] << 32;
        w28 = values[32 + valuesStart] >>> 32;
        w28 |= values[33 + valuesStart] << 23;
        w29 = values[33 + valuesStart] >>> 41;
        w29 |= values[34 + valuesStart] << 14;
        w30 = values[34 + valuesStart] >>> 50;
        w30 |= values[35 + valuesStart] << 5;
        w30 |= values[36 + valuesStart] << 60;
        w31 = values[36 + valuesStart] >>> 4;
        w31 |= values[37 + valuesStart] << 51;
        w32 = values[37 + valuesStart] >>> 13;
        w32 |= values[38 + valuesStart] << 42;
        w33 = values[38 + valuesStart] >>> 22;
        w33 |= values[39 + valuesStart] << 33;
        w34 = values[39 + valuesStart] >>> 31;
        w34 |= values[40 + valuesStart] << 24;
        w35 = values[40 + valuesStart] >>> 40;
        w35 |= values[41 + valuesStart] << 15;
        w36 = values[41 + valuesStart] >>> 49;
        w36 |= values[42 + valuesStart] << 6;
        w36 |= values[43 + valuesStart] << 61;
        w37 = values[43 + valuesStart] >>> 3;
        w37 |= values[44 + valuesStart] << 52;
        w38 = values[44 + valuesStart] >>> 12;
        w38 |= values[45 + valuesStart] << 43;
        w39 = values[45 + valuesStart] >>> 21;
        w39 |= values[46 + valuesStart] << 34;
        w40 = values[46 + valuesStart] >>> 30;
        w40 |= values[47 + valuesStart] << 25;
        w41 = values[47 + valuesStart] >>> 39;
        w41 |= values[48 + valuesStart] << 16;
        w42 = values[48 + valuesStart] >>> 48;
        w42 |= values[49 + valuesStart] << 7;
        w42 |= values[50 + valuesStart] << 62;
        w43 = values[50 + valuesStart] >>> 2;
        w43 |= values[51 + valuesStart] << 53;
        w44 = values[51 + valuesStart] >>> 11;
        w44 |= values[52 + valuesStart] << 44;
        w45 = values[52 + valuesStart] >>> 20;
        w45 |= values[53 + valuesStart] << 35;
        w46 = values[53 + valuesStart] >>> 29;
        w46 |= values[54 + valuesStart] << 26;
        w47 = values[54 + valuesStart] >>> 38;
        w47 |= values[55 + valuesStart] << 17;
        w48 = values[55 + valuesStart] >>> 47;
        w48 |= values[56 + valuesStart] << 8;
        w48 |= values[57 + valuesStart] << 63;
        w49 = values[57 + valuesStart] >>> 1;
        w49 |= values[58 + valuesStart] << 54;
        w50 = values[58 + valuesStart] >>> 10;
        w50 |= values[59 + valuesStart] << 45;
        w51 = values[59 + valuesStart] >>> 19;
        w51 |= values[60 + valuesStart] << 36;
        w52 = values[60 + valuesStart] >>> 28;
        w52 |= values[61 + valuesStart] << 27;
        w53 = values[61 + valuesStart] >>> 37;
        w53 |= values[62 + valuesStart] << 18;
        w54 = values[62 + valuesStart] >>> 46;
        w54 |= values[63 + valuesStart] << 9;
        // Write to 440 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        UnsafeUtil.putLong(384 + packedPtr, w48);
        UnsafeUtil.putLong(392 + packedPtr, w49);
        UnsafeUtil.putLong(400 + packedPtr, w50);
        UnsafeUtil.putLong(408 + packedPtr, w51);
        UnsafeUtil.putLong(416 + packedPtr, w52);
        UnsafeUtil.putLong(424 + packedPtr, w53);
        UnsafeUtil.putLong(432 + packedPtr, w54);
        return 440 + packedPtr;
    }

    /**
     * Packs 64 56-bit values into 448 bytes, touching 56 words.
     */
    private static long pack56(long[] values, int valuesStart, long packedPtr) {
        // Touching 56 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        long w48;
        long w49;
        long w50;
        long w51;
        long w52;
        long w53;
        long w54;
        long w55;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 56;
        w1 = values[1 + valuesStart] >>> 8;
        w1 |= values[2 + valuesStart] << 48;
        w2 = values[2 + valuesStart] >>> 16;
        w2 |= values[3 + valuesStart] << 40;
        w3 = values[3 + valuesStart] >>> 24;
        w3 |= values[4 + valuesStart] << 32;
        w4 = values[4 + valuesStart] >>> 32;
        w4 |= values[5 + valuesStart] << 24;
        w5 = values[5 + valuesStart] >>> 40;
        w5 |= values[6 + valuesStart] << 16;
        w6 = values[6 + valuesStart] >>> 48;
        w6 |= values[7 + valuesStart] << 8;
        w7 = values[8 + valuesStart];
        w7 |= values[9 + valuesStart] << 56;
        w8 = values[9 + valuesStart] >>> 8;
        w8 |= values[10 + valuesStart] << 48;
        w9 = values[10 + valuesStart] >>> 16;
        w9 |= values[11 + valuesStart] << 40;
        w10 = values[11 + valuesStart] >>> 24;
        w10 |= values[12 + valuesStart] << 32;
        w11 = values[12 + valuesStart] >>> 32;
        w11 |= values[13 + valuesStart] << 24;
        w12 = values[13 + valuesStart] >>> 40;
        w12 |= values[14 + valuesStart] << 16;
        w13 = values[14 + valuesStart] >>> 48;
        w13 |= values[15 + valuesStart] << 8;
        w14 = values[16 + valuesStart];
        w14 |= values[17 + valuesStart] << 56;
        w15 = values[17 + valuesStart] >>> 8;
        w15 |= values[18 + valuesStart] << 48;
        w16 = values[18 + valuesStart] >>> 16;
        w16 |= values[19 + valuesStart] << 40;
        w17 = values[19 + valuesStart] >>> 24;
        w17 |= values[20 + valuesStart] << 32;
        w18 = values[20 + valuesStart] >>> 32;
        w18 |= values[21 + valuesStart] << 24;
        w19 = values[21 + valuesStart] >>> 40;
        w19 |= values[22 + valuesStart] << 16;
        w20 = values[22 + valuesStart] >>> 48;
        w20 |= values[23 + valuesStart] << 8;
        w21 = values[24 + valuesStart];
        w21 |= values[25 + valuesStart] << 56;
        w22 = values[25 + valuesStart] >>> 8;
        w22 |= values[26 + valuesStart] << 48;
        w23 = values[26 + valuesStart] >>> 16;
        w23 |= values[27 + valuesStart] << 40;
        w24 = values[27 + valuesStart] >>> 24;
        w24 |= values[28 + valuesStart] << 32;
        w25 = values[28 + valuesStart] >>> 32;
        w25 |= values[29 + valuesStart] << 24;
        w26 = values[29 + valuesStart] >>> 40;
        w26 |= values[30 + valuesStart] << 16;
        w27 = values[30 + valuesStart] >>> 48;
        w27 |= values[31 + valuesStart] << 8;
        w28 = values[32 + valuesStart];
        w28 |= values[33 + valuesStart] << 56;
        w29 = values[33 + valuesStart] >>> 8;
        w29 |= values[34 + valuesStart] << 48;
        w30 = values[34 + valuesStart] >>> 16;
        w30 |= values[35 + valuesStart] << 40;
        w31 = values[35 + valuesStart] >>> 24;
        w31 |= values[36 + valuesStart] << 32;
        w32 = values[36 + valuesStart] >>> 32;
        w32 |= values[37 + valuesStart] << 24;
        w33 = values[37 + valuesStart] >>> 40;
        w33 |= values[38 + valuesStart] << 16;
        w34 = values[38 + valuesStart] >>> 48;
        w34 |= values[39 + valuesStart] << 8;
        w35 = values[40 + valuesStart];
        w35 |= values[41 + valuesStart] << 56;
        w36 = values[41 + valuesStart] >>> 8;
        w36 |= values[42 + valuesStart] << 48;
        w37 = values[42 + valuesStart] >>> 16;
        w37 |= values[43 + valuesStart] << 40;
        w38 = values[43 + valuesStart] >>> 24;
        w38 |= values[44 + valuesStart] << 32;
        w39 = values[44 + valuesStart] >>> 32;
        w39 |= values[45 + valuesStart] << 24;
        w40 = values[45 + valuesStart] >>> 40;
        w40 |= values[46 + valuesStart] << 16;
        w41 = values[46 + valuesStart] >>> 48;
        w41 |= values[47 + valuesStart] << 8;
        w42 = values[48 + valuesStart];
        w42 |= values[49 + valuesStart] << 56;
        w43 = values[49 + valuesStart] >>> 8;
        w43 |= values[50 + valuesStart] << 48;
        w44 = values[50 + valuesStart] >>> 16;
        w44 |= values[51 + valuesStart] << 40;
        w45 = values[51 + valuesStart] >>> 24;
        w45 |= values[52 + valuesStart] << 32;
        w46 = values[52 + valuesStart] >>> 32;
        w46 |= values[53 + valuesStart] << 24;
        w47 = values[53 + valuesStart] >>> 40;
        w47 |= values[54 + valuesStart] << 16;
        w48 = values[54 + valuesStart] >>> 48;
        w48 |= values[55 + valuesStart] << 8;
        w49 = values[56 + valuesStart];
        w49 |= values[57 + valuesStart] << 56;
        w50 = values[57 + valuesStart] >>> 8;
        w50 |= values[58 + valuesStart] << 48;
        w51 = values[58 + valuesStart] >>> 16;
        w51 |= values[59 + valuesStart] << 40;
        w52 = values[59 + valuesStart] >>> 24;
        w52 |= values[60 + valuesStart] << 32;
        w53 = values[60 + valuesStart] >>> 32;
        w53 |= values[61 + valuesStart] << 24;
        w54 = values[61 + valuesStart] >>> 40;
        w54 |= values[62 + valuesStart] << 16;
        w55 = values[62 + valuesStart] >>> 48;
        w55 |= values[63 + valuesStart] << 8;
        // Write to 448 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        UnsafeUtil.putLong(384 + packedPtr, w48);
        UnsafeUtil.putLong(392 + packedPtr, w49);
        UnsafeUtil.putLong(400 + packedPtr, w50);
        UnsafeUtil.putLong(408 + packedPtr, w51);
        UnsafeUtil.putLong(416 + packedPtr, w52);
        UnsafeUtil.putLong(424 + packedPtr, w53);
        UnsafeUtil.putLong(432 + packedPtr, w54);
        UnsafeUtil.putLong(440 + packedPtr, w55);
        return 448 + packedPtr;
    }

    /**
     * Packs 64 57-bit values into 456 bytes, touching 57 words.
     */
    private static long pack57(long[] values, int valuesStart, long packedPtr) {
        // Touching 57 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        long w48;
        long w49;
        long w50;
        long w51;
        long w52;
        long w53;
        long w54;
        long w55;
        long w56;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 57;
        w1 = values[1 + valuesStart] >>> 7;
        w1 |= values[2 + valuesStart] << 50;
        w2 = values[2 + valuesStart] >>> 14;
        w2 |= values[3 + valuesStart] << 43;
        w3 = values[3 + valuesStart] >>> 21;
        w3 |= values[4 + valuesStart] << 36;
        w4 = values[4 + valuesStart] >>> 28;
        w4 |= values[5 + valuesStart] << 29;
        w5 = values[5 + valuesStart] >>> 35;
        w5 |= values[6 + valuesStart] << 22;
        w6 = values[6 + valuesStart] >>> 42;
        w6 |= values[7 + valuesStart] << 15;
        w7 = values[7 + valuesStart] >>> 49;
        w7 |= values[8 + valuesStart] << 8;
        w8 = values[8 + valuesStart] >>> 56;
        w8 |= values[9 + valuesStart] << 1;
        w8 |= values[10 + valuesStart] << 58;
        w9 = values[10 + valuesStart] >>> 6;
        w9 |= values[11 + valuesStart] << 51;
        w10 = values[11 + valuesStart] >>> 13;
        w10 |= values[12 + valuesStart] << 44;
        w11 = values[12 + valuesStart] >>> 20;
        w11 |= values[13 + valuesStart] << 37;
        w12 = values[13 + valuesStart] >>> 27;
        w12 |= values[14 + valuesStart] << 30;
        w13 = values[14 + valuesStart] >>> 34;
        w13 |= values[15 + valuesStart] << 23;
        w14 = values[15 + valuesStart] >>> 41;
        w14 |= values[16 + valuesStart] << 16;
        w15 = values[16 + valuesStart] >>> 48;
        w15 |= values[17 + valuesStart] << 9;
        w16 = values[17 + valuesStart] >>> 55;
        w16 |= values[18 + valuesStart] << 2;
        w16 |= values[19 + valuesStart] << 59;
        w17 = values[19 + valuesStart] >>> 5;
        w17 |= values[20 + valuesStart] << 52;
        w18 = values[20 + valuesStart] >>> 12;
        w18 |= values[21 + valuesStart] << 45;
        w19 = values[21 + valuesStart] >>> 19;
        w19 |= values[22 + valuesStart] << 38;
        w20 = values[22 + valuesStart] >>> 26;
        w20 |= values[23 + valuesStart] << 31;
        w21 = values[23 + valuesStart] >>> 33;
        w21 |= values[24 + valuesStart] << 24;
        w22 = values[24 + valuesStart] >>> 40;
        w22 |= values[25 + valuesStart] << 17;
        w23 = values[25 + valuesStart] >>> 47;
        w23 |= values[26 + valuesStart] << 10;
        w24 = values[26 + valuesStart] >>> 54;
        w24 |= values[27 + valuesStart] << 3;
        w24 |= values[28 + valuesStart] << 60;
        w25 = values[28 + valuesStart] >>> 4;
        w25 |= values[29 + valuesStart] << 53;
        w26 = values[29 + valuesStart] >>> 11;
        w26 |= values[30 + valuesStart] << 46;
        w27 = values[30 + valuesStart] >>> 18;
        w27 |= values[31 + valuesStart] << 39;
        w28 = values[31 + valuesStart] >>> 25;
        w28 |= values[32 + valuesStart] << 32;
        w29 = values[32 + valuesStart] >>> 32;
        w29 |= values[33 + valuesStart] << 25;
        w30 = values[33 + valuesStart] >>> 39;
        w30 |= values[34 + valuesStart] << 18;
        w31 = values[34 + valuesStart] >>> 46;
        w31 |= values[35 + valuesStart] << 11;
        w32 = values[35 + valuesStart] >>> 53;
        w32 |= values[36 + valuesStart] << 4;
        w32 |= values[37 + valuesStart] << 61;
        w33 = values[37 + valuesStart] >>> 3;
        w33 |= values[38 + valuesStart] << 54;
        w34 = values[38 + valuesStart] >>> 10;
        w34 |= values[39 + valuesStart] << 47;
        w35 = values[39 + valuesStart] >>> 17;
        w35 |= values[40 + valuesStart] << 40;
        w36 = values[40 + valuesStart] >>> 24;
        w36 |= values[41 + valuesStart] << 33;
        w37 = values[41 + valuesStart] >>> 31;
        w37 |= values[42 + valuesStart] << 26;
        w38 = values[42 + valuesStart] >>> 38;
        w38 |= values[43 + valuesStart] << 19;
        w39 = values[43 + valuesStart] >>> 45;
        w39 |= values[44 + valuesStart] << 12;
        w40 = values[44 + valuesStart] >>> 52;
        w40 |= values[45 + valuesStart] << 5;
        w40 |= values[46 + valuesStart] << 62;
        w41 = values[46 + valuesStart] >>> 2;
        w41 |= values[47 + valuesStart] << 55;
        w42 = values[47 + valuesStart] >>> 9;
        w42 |= values[48 + valuesStart] << 48;
        w43 = values[48 + valuesStart] >>> 16;
        w43 |= values[49 + valuesStart] << 41;
        w44 = values[49 + valuesStart] >>> 23;
        w44 |= values[50 + valuesStart] << 34;
        w45 = values[50 + valuesStart] >>> 30;
        w45 |= values[51 + valuesStart] << 27;
        w46 = values[51 + valuesStart] >>> 37;
        w46 |= values[52 + valuesStart] << 20;
        w47 = values[52 + valuesStart] >>> 44;
        w47 |= values[53 + valuesStart] << 13;
        w48 = values[53 + valuesStart] >>> 51;
        w48 |= values[54 + valuesStart] << 6;
        w48 |= values[55 + valuesStart] << 63;
        w49 = values[55 + valuesStart] >>> 1;
        w49 |= values[56 + valuesStart] << 56;
        w50 = values[56 + valuesStart] >>> 8;
        w50 |= values[57 + valuesStart] << 49;
        w51 = values[57 + valuesStart] >>> 15;
        w51 |= values[58 + valuesStart] << 42;
        w52 = values[58 + valuesStart] >>> 22;
        w52 |= values[59 + valuesStart] << 35;
        w53 = values[59 + valuesStart] >>> 29;
        w53 |= values[60 + valuesStart] << 28;
        w54 = values[60 + valuesStart] >>> 36;
        w54 |= values[61 + valuesStart] << 21;
        w55 = values[61 + valuesStart] >>> 43;
        w55 |= values[62 + valuesStart] << 14;
        w56 = values[62 + valuesStart] >>> 50;
        w56 |= values[63 + valuesStart] << 7;
        // Write to 456 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        UnsafeUtil.putLong(384 + packedPtr, w48);
        UnsafeUtil.putLong(392 + packedPtr, w49);
        UnsafeUtil.putLong(400 + packedPtr, w50);
        UnsafeUtil.putLong(408 + packedPtr, w51);
        UnsafeUtil.putLong(416 + packedPtr, w52);
        UnsafeUtil.putLong(424 + packedPtr, w53);
        UnsafeUtil.putLong(432 + packedPtr, w54);
        UnsafeUtil.putLong(440 + packedPtr, w55);
        UnsafeUtil.putLong(448 + packedPtr, w56);
        return 456 + packedPtr;
    }

    /**
     * Packs 64 58-bit values into 464 bytes, touching 58 words.
     */
    private static long pack58(long[] values, int valuesStart, long packedPtr) {
        // Touching 58 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        long w48;
        long w49;
        long w50;
        long w51;
        long w52;
        long w53;
        long w54;
        long w55;
        long w56;
        long w57;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 58;
        w1 = values[1 + valuesStart] >>> 6;
        w1 |= values[2 + valuesStart] << 52;
        w2 = values[2 + valuesStart] >>> 12;
        w2 |= values[3 + valuesStart] << 46;
        w3 = values[3 + valuesStart] >>> 18;
        w3 |= values[4 + valuesStart] << 40;
        w4 = values[4 + valuesStart] >>> 24;
        w4 |= values[5 + valuesStart] << 34;
        w5 = values[5 + valuesStart] >>> 30;
        w5 |= values[6 + valuesStart] << 28;
        w6 = values[6 + valuesStart] >>> 36;
        w6 |= values[7 + valuesStart] << 22;
        w7 = values[7 + valuesStart] >>> 42;
        w7 |= values[8 + valuesStart] << 16;
        w8 = values[8 + valuesStart] >>> 48;
        w8 |= values[9 + valuesStart] << 10;
        w9 = values[9 + valuesStart] >>> 54;
        w9 |= values[10 + valuesStart] << 4;
        w9 |= values[11 + valuesStart] << 62;
        w10 = values[11 + valuesStart] >>> 2;
        w10 |= values[12 + valuesStart] << 56;
        w11 = values[12 + valuesStart] >>> 8;
        w11 |= values[13 + valuesStart] << 50;
        w12 = values[13 + valuesStart] >>> 14;
        w12 |= values[14 + valuesStart] << 44;
        w13 = values[14 + valuesStart] >>> 20;
        w13 |= values[15 + valuesStart] << 38;
        w14 = values[15 + valuesStart] >>> 26;
        w14 |= values[16 + valuesStart] << 32;
        w15 = values[16 + valuesStart] >>> 32;
        w15 |= values[17 + valuesStart] << 26;
        w16 = values[17 + valuesStart] >>> 38;
        w16 |= values[18 + valuesStart] << 20;
        w17 = values[18 + valuesStart] >>> 44;
        w17 |= values[19 + valuesStart] << 14;
        w18 = values[19 + valuesStart] >>> 50;
        w18 |= values[20 + valuesStart] << 8;
        w19 = values[20 + valuesStart] >>> 56;
        w19 |= values[21 + valuesStart] << 2;
        w19 |= values[22 + valuesStart] << 60;
        w20 = values[22 + valuesStart] >>> 4;
        w20 |= values[23 + valuesStart] << 54;
        w21 = values[23 + valuesStart] >>> 10;
        w21 |= values[24 + valuesStart] << 48;
        w22 = values[24 + valuesStart] >>> 16;
        w22 |= values[25 + valuesStart] << 42;
        w23 = values[25 + valuesStart] >>> 22;
        w23 |= values[26 + valuesStart] << 36;
        w24 = values[26 + valuesStart] >>> 28;
        w24 |= values[27 + valuesStart] << 30;
        w25 = values[27 + valuesStart] >>> 34;
        w25 |= values[28 + valuesStart] << 24;
        w26 = values[28 + valuesStart] >>> 40;
        w26 |= values[29 + valuesStart] << 18;
        w27 = values[29 + valuesStart] >>> 46;
        w27 |= values[30 + valuesStart] << 12;
        w28 = values[30 + valuesStart] >>> 52;
        w28 |= values[31 + valuesStart] << 6;
        w29 = values[32 + valuesStart];
        w29 |= values[33 + valuesStart] << 58;
        w30 = values[33 + valuesStart] >>> 6;
        w30 |= values[34 + valuesStart] << 52;
        w31 = values[34 + valuesStart] >>> 12;
        w31 |= values[35 + valuesStart] << 46;
        w32 = values[35 + valuesStart] >>> 18;
        w32 |= values[36 + valuesStart] << 40;
        w33 = values[36 + valuesStart] >>> 24;
        w33 |= values[37 + valuesStart] << 34;
        w34 = values[37 + valuesStart] >>> 30;
        w34 |= values[38 + valuesStart] << 28;
        w35 = values[38 + valuesStart] >>> 36;
        w35 |= values[39 + valuesStart] << 22;
        w36 = values[39 + valuesStart] >>> 42;
        w36 |= values[40 + valuesStart] << 16;
        w37 = values[40 + valuesStart] >>> 48;
        w37 |= values[41 + valuesStart] << 10;
        w38 = values[41 + valuesStart] >>> 54;
        w38 |= values[42 + valuesStart] << 4;
        w38 |= values[43 + valuesStart] << 62;
        w39 = values[43 + valuesStart] >>> 2;
        w39 |= values[44 + valuesStart] << 56;
        w40 = values[44 + valuesStart] >>> 8;
        w40 |= values[45 + valuesStart] << 50;
        w41 = values[45 + valuesStart] >>> 14;
        w41 |= values[46 + valuesStart] << 44;
        w42 = values[46 + valuesStart] >>> 20;
        w42 |= values[47 + valuesStart] << 38;
        w43 = values[47 + valuesStart] >>> 26;
        w43 |= values[48 + valuesStart] << 32;
        w44 = values[48 + valuesStart] >>> 32;
        w44 |= values[49 + valuesStart] << 26;
        w45 = values[49 + valuesStart] >>> 38;
        w45 |= values[50 + valuesStart] << 20;
        w46 = values[50 + valuesStart] >>> 44;
        w46 |= values[51 + valuesStart] << 14;
        w47 = values[51 + valuesStart] >>> 50;
        w47 |= values[52 + valuesStart] << 8;
        w48 = values[52 + valuesStart] >>> 56;
        w48 |= values[53 + valuesStart] << 2;
        w48 |= values[54 + valuesStart] << 60;
        w49 = values[54 + valuesStart] >>> 4;
        w49 |= values[55 + valuesStart] << 54;
        w50 = values[55 + valuesStart] >>> 10;
        w50 |= values[56 + valuesStart] << 48;
        w51 = values[56 + valuesStart] >>> 16;
        w51 |= values[57 + valuesStart] << 42;
        w52 = values[57 + valuesStart] >>> 22;
        w52 |= values[58 + valuesStart] << 36;
        w53 = values[58 + valuesStart] >>> 28;
        w53 |= values[59 + valuesStart] << 30;
        w54 = values[59 + valuesStart] >>> 34;
        w54 |= values[60 + valuesStart] << 24;
        w55 = values[60 + valuesStart] >>> 40;
        w55 |= values[61 + valuesStart] << 18;
        w56 = values[61 + valuesStart] >>> 46;
        w56 |= values[62 + valuesStart] << 12;
        w57 = values[62 + valuesStart] >>> 52;
        w57 |= values[63 + valuesStart] << 6;
        // Write to 464 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        UnsafeUtil.putLong(384 + packedPtr, w48);
        UnsafeUtil.putLong(392 + packedPtr, w49);
        UnsafeUtil.putLong(400 + packedPtr, w50);
        UnsafeUtil.putLong(408 + packedPtr, w51);
        UnsafeUtil.putLong(416 + packedPtr, w52);
        UnsafeUtil.putLong(424 + packedPtr, w53);
        UnsafeUtil.putLong(432 + packedPtr, w54);
        UnsafeUtil.putLong(440 + packedPtr, w55);
        UnsafeUtil.putLong(448 + packedPtr, w56);
        UnsafeUtil.putLong(456 + packedPtr, w57);
        return 464 + packedPtr;
    }

    /**
     * Packs 64 59-bit values into 472 bytes, touching 59 words.
     */
    private static long pack59(long[] values, int valuesStart, long packedPtr) {
        // Touching 59 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        long w48;
        long w49;
        long w50;
        long w51;
        long w52;
        long w53;
        long w54;
        long w55;
        long w56;
        long w57;
        long w58;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 59;
        w1 = values[1 + valuesStart] >>> 5;
        w1 |= values[2 + valuesStart] << 54;
        w2 = values[2 + valuesStart] >>> 10;
        w2 |= values[3 + valuesStart] << 49;
        w3 = values[3 + valuesStart] >>> 15;
        w3 |= values[4 + valuesStart] << 44;
        w4 = values[4 + valuesStart] >>> 20;
        w4 |= values[5 + valuesStart] << 39;
        w5 = values[5 + valuesStart] >>> 25;
        w5 |= values[6 + valuesStart] << 34;
        w6 = values[6 + valuesStart] >>> 30;
        w6 |= values[7 + valuesStart] << 29;
        w7 = values[7 + valuesStart] >>> 35;
        w7 |= values[8 + valuesStart] << 24;
        w8 = values[8 + valuesStart] >>> 40;
        w8 |= values[9 + valuesStart] << 19;
        w9 = values[9 + valuesStart] >>> 45;
        w9 |= values[10 + valuesStart] << 14;
        w10 = values[10 + valuesStart] >>> 50;
        w10 |= values[11 + valuesStart] << 9;
        w11 = values[11 + valuesStart] >>> 55;
        w11 |= values[12 + valuesStart] << 4;
        w11 |= values[13 + valuesStart] << 63;
        w12 = values[13 + valuesStart] >>> 1;
        w12 |= values[14 + valuesStart] << 58;
        w13 = values[14 + valuesStart] >>> 6;
        w13 |= values[15 + valuesStart] << 53;
        w14 = values[15 + valuesStart] >>> 11;
        w14 |= values[16 + valuesStart] << 48;
        w15 = values[16 + valuesStart] >>> 16;
        w15 |= values[17 + valuesStart] << 43;
        w16 = values[17 + valuesStart] >>> 21;
        w16 |= values[18 + valuesStart] << 38;
        w17 = values[18 + valuesStart] >>> 26;
        w17 |= values[19 + valuesStart] << 33;
        w18 = values[19 + valuesStart] >>> 31;
        w18 |= values[20 + valuesStart] << 28;
        w19 = values[20 + valuesStart] >>> 36;
        w19 |= values[21 + valuesStart] << 23;
        w20 = values[21 + valuesStart] >>> 41;
        w20 |= values[22 + valuesStart] << 18;
        w21 = values[22 + valuesStart] >>> 46;
        w21 |= values[23 + valuesStart] << 13;
        w22 = values[23 + valuesStart] >>> 51;
        w22 |= values[24 + valuesStart] << 8;
        w23 = values[24 + valuesStart] >>> 56;
        w23 |= values[25 + valuesStart] << 3;
        w23 |= values[26 + valuesStart] << 62;
        w24 = values[26 + valuesStart] >>> 2;
        w24 |= values[27 + valuesStart] << 57;
        w25 = values[27 + valuesStart] >>> 7;
        w25 |= values[28 + valuesStart] << 52;
        w26 = values[28 + valuesStart] >>> 12;
        w26 |= values[29 + valuesStart] << 47;
        w27 = values[29 + valuesStart] >>> 17;
        w27 |= values[30 + valuesStart] << 42;
        w28 = values[30 + valuesStart] >>> 22;
        w28 |= values[31 + valuesStart] << 37;
        w29 = values[31 + valuesStart] >>> 27;
        w29 |= values[32 + valuesStart] << 32;
        w30 = values[32 + valuesStart] >>> 32;
        w30 |= values[33 + valuesStart] << 27;
        w31 = values[33 + valuesStart] >>> 37;
        w31 |= values[34 + valuesStart] << 22;
        w32 = values[34 + valuesStart] >>> 42;
        w32 |= values[35 + valuesStart] << 17;
        w33 = values[35 + valuesStart] >>> 47;
        w33 |= values[36 + valuesStart] << 12;
        w34 = values[36 + valuesStart] >>> 52;
        w34 |= values[37 + valuesStart] << 7;
        w35 = values[37 + valuesStart] >>> 57;
        w35 |= values[38 + valuesStart] << 2;
        w35 |= values[39 + valuesStart] << 61;
        w36 = values[39 + valuesStart] >>> 3;
        w36 |= values[40 + valuesStart] << 56;
        w37 = values[40 + valuesStart] >>> 8;
        w37 |= values[41 + valuesStart] << 51;
        w38 = values[41 + valuesStart] >>> 13;
        w38 |= values[42 + valuesStart] << 46;
        w39 = values[42 + valuesStart] >>> 18;
        w39 |= values[43 + valuesStart] << 41;
        w40 = values[43 + valuesStart] >>> 23;
        w40 |= values[44 + valuesStart] << 36;
        w41 = values[44 + valuesStart] >>> 28;
        w41 |= values[45 + valuesStart] << 31;
        w42 = values[45 + valuesStart] >>> 33;
        w42 |= values[46 + valuesStart] << 26;
        w43 = values[46 + valuesStart] >>> 38;
        w43 |= values[47 + valuesStart] << 21;
        w44 = values[47 + valuesStart] >>> 43;
        w44 |= values[48 + valuesStart] << 16;
        w45 = values[48 + valuesStart] >>> 48;
        w45 |= values[49 + valuesStart] << 11;
        w46 = values[49 + valuesStart] >>> 53;
        w46 |= values[50 + valuesStart] << 6;
        w47 = values[50 + valuesStart] >>> 58;
        w47 |= values[51 + valuesStart] << 1;
        w47 |= values[52 + valuesStart] << 60;
        w48 = values[52 + valuesStart] >>> 4;
        w48 |= values[53 + valuesStart] << 55;
        w49 = values[53 + valuesStart] >>> 9;
        w49 |= values[54 + valuesStart] << 50;
        w50 = values[54 + valuesStart] >>> 14;
        w50 |= values[55 + valuesStart] << 45;
        w51 = values[55 + valuesStart] >>> 19;
        w51 |= values[56 + valuesStart] << 40;
        w52 = values[56 + valuesStart] >>> 24;
        w52 |= values[57 + valuesStart] << 35;
        w53 = values[57 + valuesStart] >>> 29;
        w53 |= values[58 + valuesStart] << 30;
        w54 = values[58 + valuesStart] >>> 34;
        w54 |= values[59 + valuesStart] << 25;
        w55 = values[59 + valuesStart] >>> 39;
        w55 |= values[60 + valuesStart] << 20;
        w56 = values[60 + valuesStart] >>> 44;
        w56 |= values[61 + valuesStart] << 15;
        w57 = values[61 + valuesStart] >>> 49;
        w57 |= values[62 + valuesStart] << 10;
        w58 = values[62 + valuesStart] >>> 54;
        w58 |= values[63 + valuesStart] << 5;
        // Write to 472 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        UnsafeUtil.putLong(384 + packedPtr, w48);
        UnsafeUtil.putLong(392 + packedPtr, w49);
        UnsafeUtil.putLong(400 + packedPtr, w50);
        UnsafeUtil.putLong(408 + packedPtr, w51);
        UnsafeUtil.putLong(416 + packedPtr, w52);
        UnsafeUtil.putLong(424 + packedPtr, w53);
        UnsafeUtil.putLong(432 + packedPtr, w54);
        UnsafeUtil.putLong(440 + packedPtr, w55);
        UnsafeUtil.putLong(448 + packedPtr, w56);
        UnsafeUtil.putLong(456 + packedPtr, w57);
        UnsafeUtil.putLong(464 + packedPtr, w58);
        return 472 + packedPtr;
    }

    /**
     * Packs 64 60-bit values into 480 bytes, touching 60 words.
     */
    private static long pack60(long[] values, int valuesStart, long packedPtr) {
        // Touching 60 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        long w48;
        long w49;
        long w50;
        long w51;
        long w52;
        long w53;
        long w54;
        long w55;
        long w56;
        long w57;
        long w58;
        long w59;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 60;
        w1 = values[1 + valuesStart] >>> 4;
        w1 |= values[2 + valuesStart] << 56;
        w2 = values[2 + valuesStart] >>> 8;
        w2 |= values[3 + valuesStart] << 52;
        w3 = values[3 + valuesStart] >>> 12;
        w3 |= values[4 + valuesStart] << 48;
        w4 = values[4 + valuesStart] >>> 16;
        w4 |= values[5 + valuesStart] << 44;
        w5 = values[5 + valuesStart] >>> 20;
        w5 |= values[6 + valuesStart] << 40;
        w6 = values[6 + valuesStart] >>> 24;
        w6 |= values[7 + valuesStart] << 36;
        w7 = values[7 + valuesStart] >>> 28;
        w7 |= values[8 + valuesStart] << 32;
        w8 = values[8 + valuesStart] >>> 32;
        w8 |= values[9 + valuesStart] << 28;
        w9 = values[9 + valuesStart] >>> 36;
        w9 |= values[10 + valuesStart] << 24;
        w10 = values[10 + valuesStart] >>> 40;
        w10 |= values[11 + valuesStart] << 20;
        w11 = values[11 + valuesStart] >>> 44;
        w11 |= values[12 + valuesStart] << 16;
        w12 = values[12 + valuesStart] >>> 48;
        w12 |= values[13 + valuesStart] << 12;
        w13 = values[13 + valuesStart] >>> 52;
        w13 |= values[14 + valuesStart] << 8;
        w14 = values[14 + valuesStart] >>> 56;
        w14 |= values[15 + valuesStart] << 4;
        w15 = values[16 + valuesStart];
        w15 |= values[17 + valuesStart] << 60;
        w16 = values[17 + valuesStart] >>> 4;
        w16 |= values[18 + valuesStart] << 56;
        w17 = values[18 + valuesStart] >>> 8;
        w17 |= values[19 + valuesStart] << 52;
        w18 = values[19 + valuesStart] >>> 12;
        w18 |= values[20 + valuesStart] << 48;
        w19 = values[20 + valuesStart] >>> 16;
        w19 |= values[21 + valuesStart] << 44;
        w20 = values[21 + valuesStart] >>> 20;
        w20 |= values[22 + valuesStart] << 40;
        w21 = values[22 + valuesStart] >>> 24;
        w21 |= values[23 + valuesStart] << 36;
        w22 = values[23 + valuesStart] >>> 28;
        w22 |= values[24 + valuesStart] << 32;
        w23 = values[24 + valuesStart] >>> 32;
        w23 |= values[25 + valuesStart] << 28;
        w24 = values[25 + valuesStart] >>> 36;
        w24 |= values[26 + valuesStart] << 24;
        w25 = values[26 + valuesStart] >>> 40;
        w25 |= values[27 + valuesStart] << 20;
        w26 = values[27 + valuesStart] >>> 44;
        w26 |= values[28 + valuesStart] << 16;
        w27 = values[28 + valuesStart] >>> 48;
        w27 |= values[29 + valuesStart] << 12;
        w28 = values[29 + valuesStart] >>> 52;
        w28 |= values[30 + valuesStart] << 8;
        w29 = values[30 + valuesStart] >>> 56;
        w29 |= values[31 + valuesStart] << 4;
        w30 = values[32 + valuesStart];
        w30 |= values[33 + valuesStart] << 60;
        w31 = values[33 + valuesStart] >>> 4;
        w31 |= values[34 + valuesStart] << 56;
        w32 = values[34 + valuesStart] >>> 8;
        w32 |= values[35 + valuesStart] << 52;
        w33 = values[35 + valuesStart] >>> 12;
        w33 |= values[36 + valuesStart] << 48;
        w34 = values[36 + valuesStart] >>> 16;
        w34 |= values[37 + valuesStart] << 44;
        w35 = values[37 + valuesStart] >>> 20;
        w35 |= values[38 + valuesStart] << 40;
        w36 = values[38 + valuesStart] >>> 24;
        w36 |= values[39 + valuesStart] << 36;
        w37 = values[39 + valuesStart] >>> 28;
        w37 |= values[40 + valuesStart] << 32;
        w38 = values[40 + valuesStart] >>> 32;
        w38 |= values[41 + valuesStart] << 28;
        w39 = values[41 + valuesStart] >>> 36;
        w39 |= values[42 + valuesStart] << 24;
        w40 = values[42 + valuesStart] >>> 40;
        w40 |= values[43 + valuesStart] << 20;
        w41 = values[43 + valuesStart] >>> 44;
        w41 |= values[44 + valuesStart] << 16;
        w42 = values[44 + valuesStart] >>> 48;
        w42 |= values[45 + valuesStart] << 12;
        w43 = values[45 + valuesStart] >>> 52;
        w43 |= values[46 + valuesStart] << 8;
        w44 = values[46 + valuesStart] >>> 56;
        w44 |= values[47 + valuesStart] << 4;
        w45 = values[48 + valuesStart];
        w45 |= values[49 + valuesStart] << 60;
        w46 = values[49 + valuesStart] >>> 4;
        w46 |= values[50 + valuesStart] << 56;
        w47 = values[50 + valuesStart] >>> 8;
        w47 |= values[51 + valuesStart] << 52;
        w48 = values[51 + valuesStart] >>> 12;
        w48 |= values[52 + valuesStart] << 48;
        w49 = values[52 + valuesStart] >>> 16;
        w49 |= values[53 + valuesStart] << 44;
        w50 = values[53 + valuesStart] >>> 20;
        w50 |= values[54 + valuesStart] << 40;
        w51 = values[54 + valuesStart] >>> 24;
        w51 |= values[55 + valuesStart] << 36;
        w52 = values[55 + valuesStart] >>> 28;
        w52 |= values[56 + valuesStart] << 32;
        w53 = values[56 + valuesStart] >>> 32;
        w53 |= values[57 + valuesStart] << 28;
        w54 = values[57 + valuesStart] >>> 36;
        w54 |= values[58 + valuesStart] << 24;
        w55 = values[58 + valuesStart] >>> 40;
        w55 |= values[59 + valuesStart] << 20;
        w56 = values[59 + valuesStart] >>> 44;
        w56 |= values[60 + valuesStart] << 16;
        w57 = values[60 + valuesStart] >>> 48;
        w57 |= values[61 + valuesStart] << 12;
        w58 = values[61 + valuesStart] >>> 52;
        w58 |= values[62 + valuesStart] << 8;
        w59 = values[62 + valuesStart] >>> 56;
        w59 |= values[63 + valuesStart] << 4;
        // Write to 480 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        UnsafeUtil.putLong(384 + packedPtr, w48);
        UnsafeUtil.putLong(392 + packedPtr, w49);
        UnsafeUtil.putLong(400 + packedPtr, w50);
        UnsafeUtil.putLong(408 + packedPtr, w51);
        UnsafeUtil.putLong(416 + packedPtr, w52);
        UnsafeUtil.putLong(424 + packedPtr, w53);
        UnsafeUtil.putLong(432 + packedPtr, w54);
        UnsafeUtil.putLong(440 + packedPtr, w55);
        UnsafeUtil.putLong(448 + packedPtr, w56);
        UnsafeUtil.putLong(456 + packedPtr, w57);
        UnsafeUtil.putLong(464 + packedPtr, w58);
        UnsafeUtil.putLong(472 + packedPtr, w59);
        return 480 + packedPtr;
    }

    /**
     * Packs 64 61-bit values into 488 bytes, touching 61 words.
     */
    private static long pack61(long[] values, int valuesStart, long packedPtr) {
        // Touching 61 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        long w48;
        long w49;
        long w50;
        long w51;
        long w52;
        long w53;
        long w54;
        long w55;
        long w56;
        long w57;
        long w58;
        long w59;
        long w60;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 61;
        w1 = values[1 + valuesStart] >>> 3;
        w1 |= values[2 + valuesStart] << 58;
        w2 = values[2 + valuesStart] >>> 6;
        w2 |= values[3 + valuesStart] << 55;
        w3 = values[3 + valuesStart] >>> 9;
        w3 |= values[4 + valuesStart] << 52;
        w4 = values[4 + valuesStart] >>> 12;
        w4 |= values[5 + valuesStart] << 49;
        w5 = values[5 + valuesStart] >>> 15;
        w5 |= values[6 + valuesStart] << 46;
        w6 = values[6 + valuesStart] >>> 18;
        w6 |= values[7 + valuesStart] << 43;
        w7 = values[7 + valuesStart] >>> 21;
        w7 |= values[8 + valuesStart] << 40;
        w8 = values[8 + valuesStart] >>> 24;
        w8 |= values[9 + valuesStart] << 37;
        w9 = values[9 + valuesStart] >>> 27;
        w9 |= values[10 + valuesStart] << 34;
        w10 = values[10 + valuesStart] >>> 30;
        w10 |= values[11 + valuesStart] << 31;
        w11 = values[11 + valuesStart] >>> 33;
        w11 |= values[12 + valuesStart] << 28;
        w12 = values[12 + valuesStart] >>> 36;
        w12 |= values[13 + valuesStart] << 25;
        w13 = values[13 + valuesStart] >>> 39;
        w13 |= values[14 + valuesStart] << 22;
        w14 = values[14 + valuesStart] >>> 42;
        w14 |= values[15 + valuesStart] << 19;
        w15 = values[15 + valuesStart] >>> 45;
        w15 |= values[16 + valuesStart] << 16;
        w16 = values[16 + valuesStart] >>> 48;
        w16 |= values[17 + valuesStart] << 13;
        w17 = values[17 + valuesStart] >>> 51;
        w17 |= values[18 + valuesStart] << 10;
        w18 = values[18 + valuesStart] >>> 54;
        w18 |= values[19 + valuesStart] << 7;
        w19 = values[19 + valuesStart] >>> 57;
        w19 |= values[20 + valuesStart] << 4;
        w20 = values[20 + valuesStart] >>> 60;
        w20 |= values[21 + valuesStart] << 1;
        w20 |= values[22 + valuesStart] << 62;
        w21 = values[22 + valuesStart] >>> 2;
        w21 |= values[23 + valuesStart] << 59;
        w22 = values[23 + valuesStart] >>> 5;
        w22 |= values[24 + valuesStart] << 56;
        w23 = values[24 + valuesStart] >>> 8;
        w23 |= values[25 + valuesStart] << 53;
        w24 = values[25 + valuesStart] >>> 11;
        w24 |= values[26 + valuesStart] << 50;
        w25 = values[26 + valuesStart] >>> 14;
        w25 |= values[27 + valuesStart] << 47;
        w26 = values[27 + valuesStart] >>> 17;
        w26 |= values[28 + valuesStart] << 44;
        w27 = values[28 + valuesStart] >>> 20;
        w27 |= values[29 + valuesStart] << 41;
        w28 = values[29 + valuesStart] >>> 23;
        w28 |= values[30 + valuesStart] << 38;
        w29 = values[30 + valuesStart] >>> 26;
        w29 |= values[31 + valuesStart] << 35;
        w30 = values[31 + valuesStart] >>> 29;
        w30 |= values[32 + valuesStart] << 32;
        w31 = values[32 + valuesStart] >>> 32;
        w31 |= values[33 + valuesStart] << 29;
        w32 = values[33 + valuesStart] >>> 35;
        w32 |= values[34 + valuesStart] << 26;
        w33 = values[34 + valuesStart] >>> 38;
        w33 |= values[35 + valuesStart] << 23;
        w34 = values[35 + valuesStart] >>> 41;
        w34 |= values[36 + valuesStart] << 20;
        w35 = values[36 + valuesStart] >>> 44;
        w35 |= values[37 + valuesStart] << 17;
        w36 = values[37 + valuesStart] >>> 47;
        w36 |= values[38 + valuesStart] << 14;
        w37 = values[38 + valuesStart] >>> 50;
        w37 |= values[39 + valuesStart] << 11;
        w38 = values[39 + valuesStart] >>> 53;
        w38 |= values[40 + valuesStart] << 8;
        w39 = values[40 + valuesStart] >>> 56;
        w39 |= values[41 + valuesStart] << 5;
        w40 = values[41 + valuesStart] >>> 59;
        w40 |= values[42 + valuesStart] << 2;
        w40 |= values[43 + valuesStart] << 63;
        w41 = values[43 + valuesStart] >>> 1;
        w41 |= values[44 + valuesStart] << 60;
        w42 = values[44 + valuesStart] >>> 4;
        w42 |= values[45 + valuesStart] << 57;
        w43 = values[45 + valuesStart] >>> 7;
        w43 |= values[46 + valuesStart] << 54;
        w44 = values[46 + valuesStart] >>> 10;
        w44 |= values[47 + valuesStart] << 51;
        w45 = values[47 + valuesStart] >>> 13;
        w45 |= values[48 + valuesStart] << 48;
        w46 = values[48 + valuesStart] >>> 16;
        w46 |= values[49 + valuesStart] << 45;
        w47 = values[49 + valuesStart] >>> 19;
        w47 |= values[50 + valuesStart] << 42;
        w48 = values[50 + valuesStart] >>> 22;
        w48 |= values[51 + valuesStart] << 39;
        w49 = values[51 + valuesStart] >>> 25;
        w49 |= values[52 + valuesStart] << 36;
        w50 = values[52 + valuesStart] >>> 28;
        w50 |= values[53 + valuesStart] << 33;
        w51 = values[53 + valuesStart] >>> 31;
        w51 |= values[54 + valuesStart] << 30;
        w52 = values[54 + valuesStart] >>> 34;
        w52 |= values[55 + valuesStart] << 27;
        w53 = values[55 + valuesStart] >>> 37;
        w53 |= values[56 + valuesStart] << 24;
        w54 = values[56 + valuesStart] >>> 40;
        w54 |= values[57 + valuesStart] << 21;
        w55 = values[57 + valuesStart] >>> 43;
        w55 |= values[58 + valuesStart] << 18;
        w56 = values[58 + valuesStart] >>> 46;
        w56 |= values[59 + valuesStart] << 15;
        w57 = values[59 + valuesStart] >>> 49;
        w57 |= values[60 + valuesStart] << 12;
        w58 = values[60 + valuesStart] >>> 52;
        w58 |= values[61 + valuesStart] << 9;
        w59 = values[61 + valuesStart] >>> 55;
        w59 |= values[62 + valuesStart] << 6;
        w60 = values[62 + valuesStart] >>> 58;
        w60 |= values[63 + valuesStart] << 3;
        // Write to 488 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        UnsafeUtil.putLong(384 + packedPtr, w48);
        UnsafeUtil.putLong(392 + packedPtr, w49);
        UnsafeUtil.putLong(400 + packedPtr, w50);
        UnsafeUtil.putLong(408 + packedPtr, w51);
        UnsafeUtil.putLong(416 + packedPtr, w52);
        UnsafeUtil.putLong(424 + packedPtr, w53);
        UnsafeUtil.putLong(432 + packedPtr, w54);
        UnsafeUtil.putLong(440 + packedPtr, w55);
        UnsafeUtil.putLong(448 + packedPtr, w56);
        UnsafeUtil.putLong(456 + packedPtr, w57);
        UnsafeUtil.putLong(464 + packedPtr, w58);
        UnsafeUtil.putLong(472 + packedPtr, w59);
        UnsafeUtil.putLong(480 + packedPtr, w60);
        return 488 + packedPtr;
    }

    /**
     * Packs 64 62-bit values into 496 bytes, touching 62 words.
     */
    private static long pack62(long[] values, int valuesStart, long packedPtr) {
        // Touching 62 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        long w48;
        long w49;
        long w50;
        long w51;
        long w52;
        long w53;
        long w54;
        long w55;
        long w56;
        long w57;
        long w58;
        long w59;
        long w60;
        long w61;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 62;
        w1 = values[1 + valuesStart] >>> 2;
        w1 |= values[2 + valuesStart] << 60;
        w2 = values[2 + valuesStart] >>> 4;
        w2 |= values[3 + valuesStart] << 58;
        w3 = values[3 + valuesStart] >>> 6;
        w3 |= values[4 + valuesStart] << 56;
        w4 = values[4 + valuesStart] >>> 8;
        w4 |= values[5 + valuesStart] << 54;
        w5 = values[5 + valuesStart] >>> 10;
        w5 |= values[6 + valuesStart] << 52;
        w6 = values[6 + valuesStart] >>> 12;
        w6 |= values[7 + valuesStart] << 50;
        w7 = values[7 + valuesStart] >>> 14;
        w7 |= values[8 + valuesStart] << 48;
        w8 = values[8 + valuesStart] >>> 16;
        w8 |= values[9 + valuesStart] << 46;
        w9 = values[9 + valuesStart] >>> 18;
        w9 |= values[10 + valuesStart] << 44;
        w10 = values[10 + valuesStart] >>> 20;
        w10 |= values[11 + valuesStart] << 42;
        w11 = values[11 + valuesStart] >>> 22;
        w11 |= values[12 + valuesStart] << 40;
        w12 = values[12 + valuesStart] >>> 24;
        w12 |= values[13 + valuesStart] << 38;
        w13 = values[13 + valuesStart] >>> 26;
        w13 |= values[14 + valuesStart] << 36;
        w14 = values[14 + valuesStart] >>> 28;
        w14 |= values[15 + valuesStart] << 34;
        w15 = values[15 + valuesStart] >>> 30;
        w15 |= values[16 + valuesStart] << 32;
        w16 = values[16 + valuesStart] >>> 32;
        w16 |= values[17 + valuesStart] << 30;
        w17 = values[17 + valuesStart] >>> 34;
        w17 |= values[18 + valuesStart] << 28;
        w18 = values[18 + valuesStart] >>> 36;
        w18 |= values[19 + valuesStart] << 26;
        w19 = values[19 + valuesStart] >>> 38;
        w19 |= values[20 + valuesStart] << 24;
        w20 = values[20 + valuesStart] >>> 40;
        w20 |= values[21 + valuesStart] << 22;
        w21 = values[21 + valuesStart] >>> 42;
        w21 |= values[22 + valuesStart] << 20;
        w22 = values[22 + valuesStart] >>> 44;
        w22 |= values[23 + valuesStart] << 18;
        w23 = values[23 + valuesStart] >>> 46;
        w23 |= values[24 + valuesStart] << 16;
        w24 = values[24 + valuesStart] >>> 48;
        w24 |= values[25 + valuesStart] << 14;
        w25 = values[25 + valuesStart] >>> 50;
        w25 |= values[26 + valuesStart] << 12;
        w26 = values[26 + valuesStart] >>> 52;
        w26 |= values[27 + valuesStart] << 10;
        w27 = values[27 + valuesStart] >>> 54;
        w27 |= values[28 + valuesStart] << 8;
        w28 = values[28 + valuesStart] >>> 56;
        w28 |= values[29 + valuesStart] << 6;
        w29 = values[29 + valuesStart] >>> 58;
        w29 |= values[30 + valuesStart] << 4;
        w30 = values[30 + valuesStart] >>> 60;
        w30 |= values[31 + valuesStart] << 2;
        w31 = values[32 + valuesStart];
        w31 |= values[33 + valuesStart] << 62;
        w32 = values[33 + valuesStart] >>> 2;
        w32 |= values[34 + valuesStart] << 60;
        w33 = values[34 + valuesStart] >>> 4;
        w33 |= values[35 + valuesStart] << 58;
        w34 = values[35 + valuesStart] >>> 6;
        w34 |= values[36 + valuesStart] << 56;
        w35 = values[36 + valuesStart] >>> 8;
        w35 |= values[37 + valuesStart] << 54;
        w36 = values[37 + valuesStart] >>> 10;
        w36 |= values[38 + valuesStart] << 52;
        w37 = values[38 + valuesStart] >>> 12;
        w37 |= values[39 + valuesStart] << 50;
        w38 = values[39 + valuesStart] >>> 14;
        w38 |= values[40 + valuesStart] << 48;
        w39 = values[40 + valuesStart] >>> 16;
        w39 |= values[41 + valuesStart] << 46;
        w40 = values[41 + valuesStart] >>> 18;
        w40 |= values[42 + valuesStart] << 44;
        w41 = values[42 + valuesStart] >>> 20;
        w41 |= values[43 + valuesStart] << 42;
        w42 = values[43 + valuesStart] >>> 22;
        w42 |= values[44 + valuesStart] << 40;
        w43 = values[44 + valuesStart] >>> 24;
        w43 |= values[45 + valuesStart] << 38;
        w44 = values[45 + valuesStart] >>> 26;
        w44 |= values[46 + valuesStart] << 36;
        w45 = values[46 + valuesStart] >>> 28;
        w45 |= values[47 + valuesStart] << 34;
        w46 = values[47 + valuesStart] >>> 30;
        w46 |= values[48 + valuesStart] << 32;
        w47 = values[48 + valuesStart] >>> 32;
        w47 |= values[49 + valuesStart] << 30;
        w48 = values[49 + valuesStart] >>> 34;
        w48 |= values[50 + valuesStart] << 28;
        w49 = values[50 + valuesStart] >>> 36;
        w49 |= values[51 + valuesStart] << 26;
        w50 = values[51 + valuesStart] >>> 38;
        w50 |= values[52 + valuesStart] << 24;
        w51 = values[52 + valuesStart] >>> 40;
        w51 |= values[53 + valuesStart] << 22;
        w52 = values[53 + valuesStart] >>> 42;
        w52 |= values[54 + valuesStart] << 20;
        w53 = values[54 + valuesStart] >>> 44;
        w53 |= values[55 + valuesStart] << 18;
        w54 = values[55 + valuesStart] >>> 46;
        w54 |= values[56 + valuesStart] << 16;
        w55 = values[56 + valuesStart] >>> 48;
        w55 |= values[57 + valuesStart] << 14;
        w56 = values[57 + valuesStart] >>> 50;
        w56 |= values[58 + valuesStart] << 12;
        w57 = values[58 + valuesStart] >>> 52;
        w57 |= values[59 + valuesStart] << 10;
        w58 = values[59 + valuesStart] >>> 54;
        w58 |= values[60 + valuesStart] << 8;
        w59 = values[60 + valuesStart] >>> 56;
        w59 |= values[61 + valuesStart] << 6;
        w60 = values[61 + valuesStart] >>> 58;
        w60 |= values[62 + valuesStart] << 4;
        w61 = values[62 + valuesStart] >>> 60;
        w61 |= values[63 + valuesStart] << 2;
        // Write to 496 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        UnsafeUtil.putLong(384 + packedPtr, w48);
        UnsafeUtil.putLong(392 + packedPtr, w49);
        UnsafeUtil.putLong(400 + packedPtr, w50);
        UnsafeUtil.putLong(408 + packedPtr, w51);
        UnsafeUtil.putLong(416 + packedPtr, w52);
        UnsafeUtil.putLong(424 + packedPtr, w53);
        UnsafeUtil.putLong(432 + packedPtr, w54);
        UnsafeUtil.putLong(440 + packedPtr, w55);
        UnsafeUtil.putLong(448 + packedPtr, w56);
        UnsafeUtil.putLong(456 + packedPtr, w57);
        UnsafeUtil.putLong(464 + packedPtr, w58);
        UnsafeUtil.putLong(472 + packedPtr, w59);
        UnsafeUtil.putLong(480 + packedPtr, w60);
        UnsafeUtil.putLong(488 + packedPtr, w61);
        return 496 + packedPtr;
    }

    /**
     * Packs 64 63-bit values into 504 bytes, touching 63 words.
     */
    private static long pack63(long[] values, int valuesStart, long packedPtr) {
        // Touching 63 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        long w48;
        long w49;
        long w50;
        long w51;
        long w52;
        long w53;
        long w54;
        long w55;
        long w56;
        long w57;
        long w58;
        long w59;
        long w60;
        long w61;
        long w62;
        w0 = values[valuesStart];
        w0 |= values[1 + valuesStart] << 63;
        w1 = values[1 + valuesStart] >>> 1;
        w1 |= values[2 + valuesStart] << 62;
        w2 = values[2 + valuesStart] >>> 2;
        w2 |= values[3 + valuesStart] << 61;
        w3 = values[3 + valuesStart] >>> 3;
        w3 |= values[4 + valuesStart] << 60;
        w4 = values[4 + valuesStart] >>> 4;
        w4 |= values[5 + valuesStart] << 59;
        w5 = values[5 + valuesStart] >>> 5;
        w5 |= values[6 + valuesStart] << 58;
        w6 = values[6 + valuesStart] >>> 6;
        w6 |= values[7 + valuesStart] << 57;
        w7 = values[7 + valuesStart] >>> 7;
        w7 |= values[8 + valuesStart] << 56;
        w8 = values[8 + valuesStart] >>> 8;
        w8 |= values[9 + valuesStart] << 55;
        w9 = values[9 + valuesStart] >>> 9;
        w9 |= values[10 + valuesStart] << 54;
        w10 = values[10 + valuesStart] >>> 10;
        w10 |= values[11 + valuesStart] << 53;
        w11 = values[11 + valuesStart] >>> 11;
        w11 |= values[12 + valuesStart] << 52;
        w12 = values[12 + valuesStart] >>> 12;
        w12 |= values[13 + valuesStart] << 51;
        w13 = values[13 + valuesStart] >>> 13;
        w13 |= values[14 + valuesStart] << 50;
        w14 = values[14 + valuesStart] >>> 14;
        w14 |= values[15 + valuesStart] << 49;
        w15 = values[15 + valuesStart] >>> 15;
        w15 |= values[16 + valuesStart] << 48;
        w16 = values[16 + valuesStart] >>> 16;
        w16 |= values[17 + valuesStart] << 47;
        w17 = values[17 + valuesStart] >>> 17;
        w17 |= values[18 + valuesStart] << 46;
        w18 = values[18 + valuesStart] >>> 18;
        w18 |= values[19 + valuesStart] << 45;
        w19 = values[19 + valuesStart] >>> 19;
        w19 |= values[20 + valuesStart] << 44;
        w20 = values[20 + valuesStart] >>> 20;
        w20 |= values[21 + valuesStart] << 43;
        w21 = values[21 + valuesStart] >>> 21;
        w21 |= values[22 + valuesStart] << 42;
        w22 = values[22 + valuesStart] >>> 22;
        w22 |= values[23 + valuesStart] << 41;
        w23 = values[23 + valuesStart] >>> 23;
        w23 |= values[24 + valuesStart] << 40;
        w24 = values[24 + valuesStart] >>> 24;
        w24 |= values[25 + valuesStart] << 39;
        w25 = values[25 + valuesStart] >>> 25;
        w25 |= values[26 + valuesStart] << 38;
        w26 = values[26 + valuesStart] >>> 26;
        w26 |= values[27 + valuesStart] << 37;
        w27 = values[27 + valuesStart] >>> 27;
        w27 |= values[28 + valuesStart] << 36;
        w28 = values[28 + valuesStart] >>> 28;
        w28 |= values[29 + valuesStart] << 35;
        w29 = values[29 + valuesStart] >>> 29;
        w29 |= values[30 + valuesStart] << 34;
        w30 = values[30 + valuesStart] >>> 30;
        w30 |= values[31 + valuesStart] << 33;
        w31 = values[31 + valuesStart] >>> 31;
        w31 |= values[32 + valuesStart] << 32;
        w32 = values[32 + valuesStart] >>> 32;
        w32 |= values[33 + valuesStart] << 31;
        w33 = values[33 + valuesStart] >>> 33;
        w33 |= values[34 + valuesStart] << 30;
        w34 = values[34 + valuesStart] >>> 34;
        w34 |= values[35 + valuesStart] << 29;
        w35 = values[35 + valuesStart] >>> 35;
        w35 |= values[36 + valuesStart] << 28;
        w36 = values[36 + valuesStart] >>> 36;
        w36 |= values[37 + valuesStart] << 27;
        w37 = values[37 + valuesStart] >>> 37;
        w37 |= values[38 + valuesStart] << 26;
        w38 = values[38 + valuesStart] >>> 38;
        w38 |= values[39 + valuesStart] << 25;
        w39 = values[39 + valuesStart] >>> 39;
        w39 |= values[40 + valuesStart] << 24;
        w40 = values[40 + valuesStart] >>> 40;
        w40 |= values[41 + valuesStart] << 23;
        w41 = values[41 + valuesStart] >>> 41;
        w41 |= values[42 + valuesStart] << 22;
        w42 = values[42 + valuesStart] >>> 42;
        w42 |= values[43 + valuesStart] << 21;
        w43 = values[43 + valuesStart] >>> 43;
        w43 |= values[44 + valuesStart] << 20;
        w44 = values[44 + valuesStart] >>> 44;
        w44 |= values[45 + valuesStart] << 19;
        w45 = values[45 + valuesStart] >>> 45;
        w45 |= values[46 + valuesStart] << 18;
        w46 = values[46 + valuesStart] >>> 46;
        w46 |= values[47 + valuesStart] << 17;
        w47 = values[47 + valuesStart] >>> 47;
        w47 |= values[48 + valuesStart] << 16;
        w48 = values[48 + valuesStart] >>> 48;
        w48 |= values[49 + valuesStart] << 15;
        w49 = values[49 + valuesStart] >>> 49;
        w49 |= values[50 + valuesStart] << 14;
        w50 = values[50 + valuesStart] >>> 50;
        w50 |= values[51 + valuesStart] << 13;
        w51 = values[51 + valuesStart] >>> 51;
        w51 |= values[52 + valuesStart] << 12;
        w52 = values[52 + valuesStart] >>> 52;
        w52 |= values[53 + valuesStart] << 11;
        w53 = values[53 + valuesStart] >>> 53;
        w53 |= values[54 + valuesStart] << 10;
        w54 = values[54 + valuesStart] >>> 54;
        w54 |= values[55 + valuesStart] << 9;
        w55 = values[55 + valuesStart] >>> 55;
        w55 |= values[56 + valuesStart] << 8;
        w56 = values[56 + valuesStart] >>> 56;
        w56 |= values[57 + valuesStart] << 7;
        w57 = values[57 + valuesStart] >>> 57;
        w57 |= values[58 + valuesStart] << 6;
        w58 = values[58 + valuesStart] >>> 58;
        w58 |= values[59 + valuesStart] << 5;
        w59 = values[59 + valuesStart] >>> 59;
        w59 |= values[60 + valuesStart] << 4;
        w60 = values[60 + valuesStart] >>> 60;
        w60 |= values[61 + valuesStart] << 3;
        w61 = values[61 + valuesStart] >>> 61;
        w61 |= values[62 + valuesStart] << 2;
        w62 = values[62 + valuesStart] >>> 62;
        w62 |= values[63 + valuesStart] << 1;
        // Write to 504 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        UnsafeUtil.putLong(384 + packedPtr, w48);
        UnsafeUtil.putLong(392 + packedPtr, w49);
        UnsafeUtil.putLong(400 + packedPtr, w50);
        UnsafeUtil.putLong(408 + packedPtr, w51);
        UnsafeUtil.putLong(416 + packedPtr, w52);
        UnsafeUtil.putLong(424 + packedPtr, w53);
        UnsafeUtil.putLong(432 + packedPtr, w54);
        UnsafeUtil.putLong(440 + packedPtr, w55);
        UnsafeUtil.putLong(448 + packedPtr, w56);
        UnsafeUtil.putLong(456 + packedPtr, w57);
        UnsafeUtil.putLong(464 + packedPtr, w58);
        UnsafeUtil.putLong(472 + packedPtr, w59);
        UnsafeUtil.putLong(480 + packedPtr, w60);
        UnsafeUtil.putLong(488 + packedPtr, w61);
        UnsafeUtil.putLong(496 + packedPtr, w62);
        return 504 + packedPtr;
    }

    /**
     * Packs 64 64-bit values into 512 bytes, touching 64 words.
     */
    private static long pack64(long[] values, int valuesStart, long packedPtr) {
        // Touching 64 words
        long w0;
        long w1;
        long w2;
        long w3;
        long w4;
        long w5;
        long w6;
        long w7;
        long w8;
        long w9;
        long w10;
        long w11;
        long w12;
        long w13;
        long w14;
        long w15;
        long w16;
        long w17;
        long w18;
        long w19;
        long w20;
        long w21;
        long w22;
        long w23;
        long w24;
        long w25;
        long w26;
        long w27;
        long w28;
        long w29;
        long w30;
        long w31;
        long w32;
        long w33;
        long w34;
        long w35;
        long w36;
        long w37;
        long w38;
        long w39;
        long w40;
        long w41;
        long w42;
        long w43;
        long w44;
        long w45;
        long w46;
        long w47;
        long w48;
        long w49;
        long w50;
        long w51;
        long w52;
        long w53;
        long w54;
        long w55;
        long w56;
        long w57;
        long w58;
        long w59;
        long w60;
        long w61;
        long w62;
        long w63;
        w0 = values[valuesStart];
        w1 = values[1 + valuesStart];
        w2 = values[2 + valuesStart];
        w3 = values[3 + valuesStart];
        w4 = values[4 + valuesStart];
        w5 = values[5 + valuesStart];
        w6 = values[6 + valuesStart];
        w7 = values[7 + valuesStart];
        w8 = values[8 + valuesStart];
        w9 = values[9 + valuesStart];
        w10 = values[10 + valuesStart];
        w11 = values[11 + valuesStart];
        w12 = values[12 + valuesStart];
        w13 = values[13 + valuesStart];
        w14 = values[14 + valuesStart];
        w15 = values[15 + valuesStart];
        w16 = values[16 + valuesStart];
        w17 = values[17 + valuesStart];
        w18 = values[18 + valuesStart];
        w19 = values[19 + valuesStart];
        w20 = values[20 + valuesStart];
        w21 = values[21 + valuesStart];
        w22 = values[22 + valuesStart];
        w23 = values[23 + valuesStart];
        w24 = values[24 + valuesStart];
        w25 = values[25 + valuesStart];
        w26 = values[26 + valuesStart];
        w27 = values[27 + valuesStart];
        w28 = values[28 + valuesStart];
        w29 = values[29 + valuesStart];
        w30 = values[30 + valuesStart];
        w31 = values[31 + valuesStart];
        w32 = values[32 + valuesStart];
        w33 = values[33 + valuesStart];
        w34 = values[34 + valuesStart];
        w35 = values[35 + valuesStart];
        w36 = values[36 + valuesStart];
        w37 = values[37 + valuesStart];
        w38 = values[38 + valuesStart];
        w39 = values[39 + valuesStart];
        w40 = values[40 + valuesStart];
        w41 = values[41 + valuesStart];
        w42 = values[42 + valuesStart];
        w43 = values[43 + valuesStart];
        w44 = values[44 + valuesStart];
        w45 = values[45 + valuesStart];
        w46 = values[46 + valuesStart];
        w47 = values[47 + valuesStart];
        w48 = values[48 + valuesStart];
        w49 = values[49 + valuesStart];
        w50 = values[50 + valuesStart];
        w51 = values[51 + valuesStart];
        w52 = values[52 + valuesStart];
        w53 = values[53 + valuesStart];
        w54 = values[54 + valuesStart];
        w55 = values[55 + valuesStart];
        w56 = values[56 + valuesStart];
        w57 = values[57 + valuesStart];
        w58 = values[58 + valuesStart];
        w59 = values[59 + valuesStart];
        w60 = values[60 + valuesStart];
        w61 = values[61 + valuesStart];
        w62 = values[62 + valuesStart];
        w63 = values[63 + valuesStart];
        // Write to 512 bytes
        UnsafeUtil.putLong(packedPtr, w0);
        UnsafeUtil.putLong(8 + packedPtr, w1);
        UnsafeUtil.putLong(16 + packedPtr, w2);
        UnsafeUtil.putLong(24 + packedPtr, w3);
        UnsafeUtil.putLong(32 + packedPtr, w4);
        UnsafeUtil.putLong(40 + packedPtr, w5);
        UnsafeUtil.putLong(48 + packedPtr, w6);
        UnsafeUtil.putLong(56 + packedPtr, w7);
        UnsafeUtil.putLong(64 + packedPtr, w8);
        UnsafeUtil.putLong(72 + packedPtr, w9);
        UnsafeUtil.putLong(80 + packedPtr, w10);
        UnsafeUtil.putLong(88 + packedPtr, w11);
        UnsafeUtil.putLong(96 + packedPtr, w12);
        UnsafeUtil.putLong(104 + packedPtr, w13);
        UnsafeUtil.putLong(112 + packedPtr, w14);
        UnsafeUtil.putLong(120 + packedPtr, w15);
        UnsafeUtil.putLong(128 + packedPtr, w16);
        UnsafeUtil.putLong(136 + packedPtr, w17);
        UnsafeUtil.putLong(144 + packedPtr, w18);
        UnsafeUtil.putLong(152 + packedPtr, w19);
        UnsafeUtil.putLong(160 + packedPtr, w20);
        UnsafeUtil.putLong(168 + packedPtr, w21);
        UnsafeUtil.putLong(176 + packedPtr, w22);
        UnsafeUtil.putLong(184 + packedPtr, w23);
        UnsafeUtil.putLong(192 + packedPtr, w24);
        UnsafeUtil.putLong(200 + packedPtr, w25);
        UnsafeUtil.putLong(208 + packedPtr, w26);
        UnsafeUtil.putLong(216 + packedPtr, w27);
        UnsafeUtil.putLong(224 + packedPtr, w28);
        UnsafeUtil.putLong(232 + packedPtr, w29);
        UnsafeUtil.putLong(240 + packedPtr, w30);
        UnsafeUtil.putLong(248 + packedPtr, w31);
        UnsafeUtil.putLong(256 + packedPtr, w32);
        UnsafeUtil.putLong(264 + packedPtr, w33);
        UnsafeUtil.putLong(272 + packedPtr, w34);
        UnsafeUtil.putLong(280 + packedPtr, w35);
        UnsafeUtil.putLong(288 + packedPtr, w36);
        UnsafeUtil.putLong(296 + packedPtr, w37);
        UnsafeUtil.putLong(304 + packedPtr, w38);
        UnsafeUtil.putLong(312 + packedPtr, w39);
        UnsafeUtil.putLong(320 + packedPtr, w40);
        UnsafeUtil.putLong(328 + packedPtr, w41);
        UnsafeUtil.putLong(336 + packedPtr, w42);
        UnsafeUtil.putLong(344 + packedPtr, w43);
        UnsafeUtil.putLong(352 + packedPtr, w44);
        UnsafeUtil.putLong(360 + packedPtr, w45);
        UnsafeUtil.putLong(368 + packedPtr, w46);
        UnsafeUtil.putLong(376 + packedPtr, w47);
        UnsafeUtil.putLong(384 + packedPtr, w48);
        UnsafeUtil.putLong(392 + packedPtr, w49);
        UnsafeUtil.putLong(400 + packedPtr, w50);
        UnsafeUtil.putLong(408 + packedPtr, w51);
        UnsafeUtil.putLong(416 + packedPtr, w52);
        UnsafeUtil.putLong(424 + packedPtr, w53);
        UnsafeUtil.putLong(432 + packedPtr, w54);
        UnsafeUtil.putLong(440 + packedPtr, w55);
        UnsafeUtil.putLong(448 + packedPtr, w56);
        UnsafeUtil.putLong(456 + packedPtr, w57);
        UnsafeUtil.putLong(464 + packedPtr, w58);
        UnsafeUtil.putLong(472 + packedPtr, w59);
        UnsafeUtil.putLong(480 + packedPtr, w60);
        UnsafeUtil.putLong(488 + packedPtr, w61);
        UnsafeUtil.putLong(496 + packedPtr, w62);
        UnsafeUtil.putLong(504 + packedPtr, w63);
        return 512 + packedPtr;
    }

    /**
     * Packs `valuesLength` 0-bit values.
     */
    private static long packLoop0(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 1-bit values.
     */
    private static long packLoop1(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 1) {
            word |= values[i] << shift;
            if (shift > 63) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 63) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 2-bit values.
     */
    private static long packLoop2(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 2) {
            word |= values[i] << shift;
            if (shift > 62) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 62) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 3-bit values.
     */
    private static long packLoop3(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 3) {
            word |= values[i] << shift;
            if (shift > 61) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 61) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 4-bit values.
     */
    private static long packLoop4(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 4) {
            word |= values[i] << shift;
            if (shift > 60) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 60) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 5-bit values.
     */
    private static long packLoop5(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 5) {
            word |= values[i] << shift;
            if (shift > 59) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 59) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 6-bit values.
     */
    private static long packLoop6(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 6) {
            word |= values[i] << shift;
            if (shift > 58) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 58) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 7-bit values.
     */
    private static long packLoop7(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 7) {
            word |= values[i] << shift;
            if (shift > 57) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 57) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 8-bit values.
     */
    private static long packLoop8(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 8) {
            word |= values[i] << shift;
            if (shift > 56) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 56) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 9-bit values.
     */
    private static long packLoop9(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 9) {
            word |= values[i] << shift;
            if (shift > 55) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 55) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 10-bit values.
     */
    private static long packLoop10(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 10) {
            word |= values[i] << shift;
            if (shift > 54) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 54) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 11-bit values.
     */
    private static long packLoop11(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 11) {
            word |= values[i] << shift;
            if (shift > 53) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 53) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 12-bit values.
     */
    private static long packLoop12(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 12) {
            word |= values[i] << shift;
            if (shift > 52) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 52) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 13-bit values.
     */
    private static long packLoop13(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 13) {
            word |= values[i] << shift;
            if (shift > 51) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 51) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 14-bit values.
     */
    private static long packLoop14(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 14) {
            word |= values[i] << shift;
            if (shift > 50) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 50) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 15-bit values.
     */
    private static long packLoop15(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 15) {
            word |= values[i] << shift;
            if (shift > 49) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 49) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 16-bit values.
     */
    private static long packLoop16(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 16) {
            word |= values[i] << shift;
            if (shift > 48) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 48) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 17-bit values.
     */
    private static long packLoop17(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 17) {
            word |= values[i] << shift;
            if (shift > 47) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 47) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 18-bit values.
     */
    private static long packLoop18(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 18) {
            word |= values[i] << shift;
            if (shift > 46) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 46) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 19-bit values.
     */
    private static long packLoop19(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 19) {
            word |= values[i] << shift;
            if (shift > 45) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 45) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 20-bit values.
     */
    private static long packLoop20(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 20) {
            word |= values[i] << shift;
            if (shift > 44) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 44) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 21-bit values.
     */
    private static long packLoop21(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 21) {
            word |= values[i] << shift;
            if (shift > 43) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 43) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 22-bit values.
     */
    private static long packLoop22(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 22) {
            word |= values[i] << shift;
            if (shift > 42) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 42) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 23-bit values.
     */
    private static long packLoop23(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 23) {
            word |= values[i] << shift;
            if (shift > 41) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 41) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 24-bit values.
     */
    private static long packLoop24(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 24) {
            word |= values[i] << shift;
            if (shift > 40) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 40) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 25-bit values.
     */
    private static long packLoop25(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 25) {
            word |= values[i] << shift;
            if (shift > 39) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 39) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 26-bit values.
     */
    private static long packLoop26(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 26) {
            word |= values[i] << shift;
            if (shift > 38) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 38) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 27-bit values.
     */
    private static long packLoop27(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 27) {
            word |= values[i] << shift;
            if (shift > 37) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 37) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 28-bit values.
     */
    private static long packLoop28(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 28) {
            word |= values[i] << shift;
            if (shift > 36) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 36) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 29-bit values.
     */
    private static long packLoop29(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 29) {
            word |= values[i] << shift;
            if (shift > 35) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 35) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 30-bit values.
     */
    private static long packLoop30(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 30) {
            word |= values[i] << shift;
            if (shift > 34) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 34) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 31-bit values.
     */
    private static long packLoop31(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 31) {
            word |= values[i] << shift;
            if (shift > 33) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 33) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 32-bit values.
     */
    private static long packLoop32(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 32) {
            word |= values[i] << shift;
            if (shift > 32) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 32) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 33-bit values.
     */
    private static long packLoop33(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 33) {
            word |= values[i] << shift;
            if (shift > 31) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 31) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 34-bit values.
     */
    private static long packLoop34(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 34) {
            word |= values[i] << shift;
            if (shift > 30) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 30) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 35-bit values.
     */
    private static long packLoop35(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 35) {
            word |= values[i] << shift;
            if (shift > 29) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 29) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 36-bit values.
     */
    private static long packLoop36(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 36) {
            word |= values[i] << shift;
            if (shift > 28) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 28) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 37-bit values.
     */
    private static long packLoop37(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 37) {
            word |= values[i] << shift;
            if (shift > 27) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 27) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 38-bit values.
     */
    private static long packLoop38(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 38) {
            word |= values[i] << shift;
            if (shift > 26) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 26) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 39-bit values.
     */
    private static long packLoop39(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 39) {
            word |= values[i] << shift;
            if (shift > 25) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 25) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 40-bit values.
     */
    private static long packLoop40(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 40) {
            word |= values[i] << shift;
            if (shift > 24) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 24) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 41-bit values.
     */
    private static long packLoop41(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 41) {
            word |= values[i] << shift;
            if (shift > 23) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 23) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 42-bit values.
     */
    private static long packLoop42(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 42) {
            word |= values[i] << shift;
            if (shift > 22) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 22) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 43-bit values.
     */
    private static long packLoop43(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 43) {
            word |= values[i] << shift;
            if (shift > 21) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 21) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 44-bit values.
     */
    private static long packLoop44(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 44) {
            word |= values[i] << shift;
            if (shift > 20) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 20) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 45-bit values.
     */
    private static long packLoop45(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 45) {
            word |= values[i] << shift;
            if (shift > 19) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 19) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 46-bit values.
     */
    private static long packLoop46(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 46) {
            word |= values[i] << shift;
            if (shift > 18) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 18) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 47-bit values.
     */
    private static long packLoop47(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 47) {
            word |= values[i] << shift;
            if (shift > 17) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 17) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 48-bit values.
     */
    private static long packLoop48(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 48) {
            word |= values[i] << shift;
            if (shift > 16) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 16) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 49-bit values.
     */
    private static long packLoop49(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 49) {
            word |= values[i] << shift;
            if (shift > 15) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 15) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 50-bit values.
     */
    private static long packLoop50(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 50) {
            word |= values[i] << shift;
            if (shift > 14) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 14) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 51-bit values.
     */
    private static long packLoop51(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 51) {
            word |= values[i] << shift;
            if (shift > 13) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 13) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 52-bit values.
     */
    private static long packLoop52(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 52) {
            word |= values[i] << shift;
            if (shift > 12) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 12) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 53-bit values.
     */
    private static long packLoop53(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 53) {
            word |= values[i] << shift;
            if (shift > 11) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 11) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 54-bit values.
     */
    private static long packLoop54(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 54) {
            word |= values[i] << shift;
            if (shift > 10) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 10) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 55-bit values.
     */
    private static long packLoop55(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 55) {
            word |= values[i] << shift;
            if (shift > 9) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 9) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 56-bit values.
     */
    private static long packLoop56(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 56) {
            word |= values[i] << shift;
            if (shift > 8) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 8) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 57-bit values.
     */
    private static long packLoop57(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 57) {
            word |= values[i] << shift;
            if (shift > 7) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 7) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 58-bit values.
     */
    private static long packLoop58(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 58) {
            word |= values[i] << shift;
            if (shift > 6) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 6) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 59-bit values.
     */
    private static long packLoop59(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 59) {
            word |= values[i] << shift;
            if (shift > 5) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 5) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 60-bit values.
     */
    private static long packLoop60(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 60) {
            word |= values[i] << shift;
            if (shift > 4) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 4) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 61-bit values.
     */
    private static long packLoop61(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 61) {
            word |= values[i] << shift;
            if (shift > 3) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 3) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 62-bit values.
     */
    private static long packLoop62(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 62) {
            word |= values[i] << shift;
            if (shift > 2) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 2) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 63-bit values.
     */
    private static long packLoop63(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 63) {
            word |= values[i] << shift;
            if (shift > 1) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 1) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        if (shift != 0) {
            UnsafeUtil.putLong(packedPtr, word);
            packedPtr += 8;
        }
        return packedPtr;
    }

    /**
     * Packs `valuesLength` 64-bit values.
     */
    private static long packLoop64(long[] values, int valuesStart, int valuesLength, long packedPtr) {
        long word = 0;
        int shift = 0;
        for (int i = valuesStart; i < valuesStart + valuesLength; i += 1, shift += 64) {
            word |= values[i] << shift;
            if (shift > 0) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = values[i] >>> 64 - shift;
                shift -= 64;
            } else if (shift == 0) {
                UnsafeUtil.putLong(packedPtr, word);
                packedPtr += 8;
                word = 0;
                shift -= 64;
            }
        }
        UnsafeUtil.putLong(packedPtr, word);
        packedPtr += 8;
        return packedPtr;
    }
}
